java虚拟机指令dup详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

java虚拟机指令dup详解
本⽂实例为⼤家介绍了java虚拟机指令dup,供⼤家参考,具体内容如下
举个例⼦:
public class ExceptionTest{
void cantBeZero(int i) throws Exception{
throw new Exception();
}
}
上⾯代码编译后的字节码指令如下:
void cantBeZero(int) throws ng.Exception;
descriptor: (I)V
flags:
Code:
stack=2, locals=2, args_size=2
0: iload_1
1: ifne 12
4: new #2
// class java/lang/Exception
7: dup
8: invokespecial #3
// Method java/lang/Exception."<init>":()V
11: athrow
12: return
1) 其中new指令在java堆上为Exception对象分配内存空间,并将地址压⼊操作数栈顶;
2) 然后dup指令为复制操作数栈顶值,并将其压⼊栈顶,也就是说此时操作数栈上有连续相同的两个对象地址;
3) invokespecial指令调⽤实例初始化⽅法<init>:()V,注意这个⽅法是⼀个实例⽅法,所以需要从操作数栈顶弹出⼀个this引⽤,也就是说这⼀步会弹出⼀个之前⼊栈的对象地址;
4) athrow指令从操作数栈顶取出⼀个引⽤类型的值,并抛出;
5) 最后由return指令结束⽅法。

从上⾯的五个步骤中可以看出,需要从栈顶弹出两个实例对象的引⽤,这就是为什么会在new指令下⾯有⼀个dup指令,其实对于每⼀个new指令来说⼀般编译器都会在其下⾯⽣成
⼀个dup指令,这是因为实例的初始化⽅法肯定需要⽤到⼀次,然后第⼆个留给程序员使⽤,例如给变量赋值,抛出异常等,如果我们不⽤,那编译器也会⽣成dup指令,在初始化⽅法调⽤完成后再从栈顶pop出来。

例如我们仅仅创建⼀个对象⽽不做任何操作,例如:
void cantBeZero(int i) throws Exception{
new Exception();
}
上⾯的代码仅仅创建了⼀个Exception对象,⽽没有做任何操作。

其编译后的字节码指令如下:
void cantBeZero(int) throws ng.Exception;
descriptor: (I)V
flags:
Code:
stack=2, locals=2, args_size=2
0: new #2 // class java/lang/Exception
3: dup
4: invokespecial #3 // Method java/lang/Exception."<init>":()V
7: pop
8: return
也会⽣成⼀个dup指令,只不过在调⽤完实例初始化⽅法后,将重复的实例引⽤⼜pop出栈了。

不过这种情况基本不会出现在
我们的代码中,因为我们创建的每⼀个对象都应该是有⽤的。

通过上⾯的例⼦你应该⽐较清楚的理解了为什么创建对象时总会有⼀个dup指令了。

以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

相关文档
最新文档