Java字节码new之后为什么会有dup

Java虚拟机 专栏收录该内容
4 篇文章 0 订阅

在看《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》这本书时,有几处的字节码在new之后会紧接着出现dup指令,我么以书中253页的字节码为例,说明dup指令的作用。

其中Java代码为:

public class DynamicDispatch {

	static abstract class Human {
		protected abstract void sayHello();
	}

	static class Man extends Human {
		@Override
		protected void sayHello() {
			System.out.println("man say hello");
		}
	}

	static class Woman extends Human {
		@Override
		protected void sayHello() {
			System.out.println("woman say hello");
		}
	}

	public static void main(String[] args) {
		Human man = new Man();
		Human woman = new Woman();
		man.sayHello();
		woman.sayHello();
		man = new Woman();
		man.sayHello();
	}
}

对应的字节码为:

 public static void main(java.lang.String[]);
   Code:
      0: new           #16 // class jvm/fenixsoft/DynamicDispath$Man
      3: dup
      4: invokespecial #18 // Method jvm/fenixsoft/DynamicDispach$Man."<init>":()V
      7: astore_1
      8: new           #19 // class jvm/fenixsoft/DynamicDispath$Woman
     11: dup
     12: invokespecial #21 // Method jvm/fenixsoft/DynamicDispach$Woman."<init>":()V
     15: astore_2
     16: aload_1
     17: invokevirtual #22 // Method jvm/fenixsoft/DynamicDispach$Human.sayHello:()V
     20: aload_2
     21: invokevirtual #22 // Method jvm/fenixsoft/DynamicDispach$Human.sayHello:()V
     24: new           #19 // class jvm/fenixsoft/DynamicDispath$Woman
     27: dup
     28: invokespecial #21 // Method jvm/fenixsoft/DynamicDispach$Woman."<init>":()V
     31: astore_1
     32: aload_1
     33: invokevirtual #22 // Method jvm/fenixsoft/DynamicDispach$Human.sayHello:()V
     36: return

关于dup指令的作用,在《深入理解Java虚拟机》这本书中是这么描述的。这是一个操作数栈管理指令,负责复制栈顶(注意,这个栈指的是操作数栈)一个或者两个数值并将复制值或双份的复制值重新压人栈顶。

简单理解就是给操作数栈栈顶的元素弄了一个备份。

那么为什么要进行备份呢?

一开始是new指令在堆上分配了内存并向操作数栈压入了指向这段内存的引用,之后dup指令又备份了一份,那么操作数栈顶就有两个,再后是调用invokespecial #18指令进行初始化,此时会消耗一个引用作为传给构造器的“this”参数,那么还剩下一个引用,会被astore_1指令存储到局部变量表中。

  • 0
    点赞
  • 2
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值