欢迎来到代码驿站!

JAVA代码

当前位置:首页 > 软件编程 > JAVA代码

java虚拟机指令dup详解

时间:2021-06-25 09:26:21|栏目:JAVA代码|点击:

本文实例为大家介绍了java虚拟机指令dup,供大家参考,具体内容如下

举个例子:

public class ExceptionTest{

  void cantBeZero(int i) throws Exception{
    throw new Exception();

  }

}

上面代码编译后的字节码指令如下:

void cantBeZero(int) throws java.lang.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 java.lang.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指令了。

上一篇:Java中自动装箱、拆箱引起的耗时详解

栏    目:JAVA代码

下一篇:java实现二分法查找出数组重复数字

本文标题:java虚拟机指令dup详解

本文地址:http://www.codeinn.net/misctech/147641.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有