目录
1.问题的提出:
2.如何对class文件进行反汇编
步骤(1)
步骤(2)
步骤 (3)
步骤 (4)
步骤(5)
步骤(6)
1.将常量压入到操作数栈中的一些命令
2.关于指令的含义
3. 对于a=a++解释
1.问题的提出:
在学过自增自减后的运算符后,对于下面的代码你能不使用计算机直接算结果为多少吗?
public class Demo{
public static void main(String[] args) {
int a=10;
a=a++;
System.out.println(a);
}
}
你可能毫不犹豫说出,结果为11,如果是这样,那么你就掉到坑里了,正确答案是这个代码结果为10.
为甚么结果为10呢,这里就涉及到了Java中栈帧的知识,首先需要我们从字节码的层面来进行分析。但是字节码文件我们直接看是看不懂的,所以我们需要借助一些其他工具来进行实现。
2.如何对class文件进行反汇编
步骤(1)
打开你的idea编译器,然后根据自己需要所反汇编的代码来进行创建class文件,如下图所示:
这个就是上面问题所需要求得结果
步骤(2)
接着打开反汇编工具
步骤 (3)
接着打开该class文件的位置,下面是我生成class文件的位置,注意,生成class文件的位置在你项目下的out文件夹的里面
步骤 (4)
将得到的路径进行拷贝到idea反汇编的位置
步骤(5)
接着就会出现很多进行反汇编之后的结果,我们只需关心下面的内容即可,因为下面的main方法当中是我们需要的。
到了这一步我们还是比较迷茫,因为这里的很多关键字我们都不知道是什么意思,接下来就是查询这些关键字的意思,bipush,istore等
步骤(6)
反汇编之中的关键字的解析
1.将常量压入到操作数栈中的一些命令
iconst_1:这个操作是 int 值为 1~5 的时候。
bipush x (x 为实际数值):如果是 -128~127 这个范围是使用该命令的。
sipush x : -2^15~2^15-1 这个范围是使用的这个命令的。
ldc:-2^31~2^31-1 这个范围是使用这个命令的。
istore_1:将一个数值从操作数栈存储到局部变量表中
iinc:对指定槽位的变量进行加法操作
如上面的 iinc 1,1 相当于是给1号槽位的变量值加1
iload_1:将1号槽中的变量押入到操作数栈中
2.关于指令的含义
根据下面代码可得,其中的参数只有args一个
局部变量表中参数的个数(2个):
3. 对于a=a++解释
现在我们就可以分析上面反编译的结果了
操作的示意图:
最终a的值没有改变,这是因为首先将a的初始值保存起来,然后给a加1,接着再将初始值赋给a。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)