摘要:当你学会了java语言之后,你写了一些代码,而后你想要执行你的代码,来达成某些性能。那么,你都晓得这段java代码都是如何执行的吗?
本文分享自华为云社区《一段java代码是如何执行的》,原文作者:技术火炬手 。
当你学会了java语言之后,你写了一些代码,而后你想要执行你的代码,来达成某些性能。那么,你都晓得这段代码都是如何执行的吗?
1. 编译成class
家喻户晓,java代码是不能间接在jvm上执行的,执行的是class文件,将java代码编程class文件,须要编译
罕用的编译办法是:javac xxx.java
但目前常见的java编辑工具,如eclipse和ideal都自带主动编译动能
2. jvm的形成
让咱们回顾一下jvm的形成:
主题上分为五个局部:
办法区,本地办法栈,java堆,java栈,程序计数器
其中,java栈,本地办法栈,程序计数器为线程公有,其余为线程共享
那么,办法在哪个中央执行呢?
java栈。
栈的遵循的形式是先进后出,java栈中办法的执行也遵循此法则,办法执行的步骤又称为栈帧。
3. 办法的程序执行和栈帧
上代码:
Java 代码
public class Main { public static void a(){ b(); } public static void b(){ c(); } public static void c(){ System.out.println("Hello world!"); } public static void main(String[] args) { a(); }}
下面是一段很简略的代码,主体上就是:
(1)一个Main类
(2)下面定义了一个main办法
(3)该main办法调用了静态方法a
(4)办法a调用办法b
(5)办法b调用办法c
(6)办法c打印了“Hello world!”
前文说过,java定义的非本地办法都是在java栈内执行的,一办法一栈帧
所以假如
mian办法对应栈帧m
- a办法对应栈帧a
- b办法对应栈帧b
- c办法对应栈帧c
依据办法的调用,入栈程序为:m,a,b,c
所以,栈帧出栈(即办法执行)程序为:c,b,a,m
4. class文件反编译过后的样子
上一节,办法或栈帧在java栈的执行程序,但在办法体内的内容是怎么执行的呢。
前文提到,jvm执行的是class文件,而class文件内是什么?
class文件内是一组指令集。
如何证实呢,还是再看一段代码。
Java 代码
public class Calculator{ public int add(){ int n = 10; int m = 20; int r = n + m; return r; } public static void main(String[] args) { Calculator calculator = new Calculator(); int a = calculator.add(); System.out.println(a); }}
如上代码,实现的性能是:
(1)定义两个变量,相加
(2)main办法new对象,调用办法
但,class文件是不能够间接查看的。
咱们能够采纳反编译的办法,反编译命令:
javap -c xxx.class
上述文件反编译后的样子如下:
每个办法上面的Code,都是一组指令集。
5. 指令集详解
在探讨指令集之前,首先要讲一个概念,那就是对栈帧进一步拆分。
栈帧一共分为四个局部:局部变量表、操作数栈、动静链接、办法返回地址
其中,局部变量表和操作数栈是最重要的两个局部,局部变量表寄存在办法中定义的局部变量,操作数栈相当于jvm的一个缓存,所有的操作都必须在此处进行,所有的变量都必须加载到操作数栈能力被应用。所以,所谓指令,就是在局部变量表和操作数栈来回倒腾的过程。
上面对指令进行分类解说:
(1)入栈指令
整型入栈指令:
- 取值-1~5采纳iconst指令;
- 取值-128~127采纳bipush指令;
- 取值-32768~32767采纳sipush指令;
- 取值-2147483648~2147483647采纳ldc指令。
非整型入栈指令:
- float,String类型也应用ldc指令
- double和long类型应用ldc_2w
- boolean类型视作0和1
- null的入栈指令为:aconst_null
(2)存储指令
将操作数栈中的常量保留在局部变量表中的某个地位
如:
- istore_1:将下面入栈的整型常量保留在局部变量表中的第1个地位
- fstore_2:将下面入栈的浮点常量保留在局部变量表中的第2个地位
- dstore_10:将下面入栈的双浮点常量保留在局部变量表中的第10个地位
- lstore_20:将下面入栈的长整常量保留在局部变量表中的第20个地位
- astore_100:将下面入栈的援用常量保留在局部变量表中的第100个地位
(3)变量入栈指令
- iload_1:局部变量表中的第1个地位的整型变量入栈
- fload_2:局部变量表中的第1个地位的浮点型变量入栈
- dload_10:局部变量表中的第1个地位的双浮点型变量入栈
- lload_20:局部变量表中的第1个地位的长整型变量入栈
- aload_100:局部变量表中的第100个地位的援用型变量入栈
(4)计算指令
- 加:iadd、ladd、fadd、dadd
减:isub、lsub、fsub、dsub
乘:imul、lmul、fmul、dmul
除:idiv、ldiv、fdiv、ddiv
留神:栈顶计算,一次只能计算一个表达式
点击关注,第一工夫理解华为云陈腐技术~