龙空技术网

Java基础知识:为什么new之后会有dup呢?

宁静知行者 46

前言:

而今看官们对“java里面new什么意思”都比较珍视,小伙伴们都想要知道一些“java里面new什么意思”的相关文章。那么小编同时在网络上网罗了一些有关“java里面new什么意思””的相关内容,希望咱们能喜欢,大家快快来学习一下吧!

前言

前两天碰到一个小朋友,他提出了一个问题,先看下代码

public static void main(String[] args) {    Test1 test1 = new Test1();    test1.c("test1");    System.out.println(test1.getName());}

生成的字节码如下

public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=2, locals=2, args_size=1         0: new           #2                  // class Test1         3: dup         4: invokespecial #3                  // Method "<init>":()V         7: astore_1         8: aload_1         9: ldc           #4                  // String test1        11: invokevirtual #5                  // Method c:(Ljava/lang/String;)V        14: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;        17: aload_1        18: invokevirtual #7                  // Method getName:()Ljava/lang/String;        21: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V        24: return

他的问题是:在new指令后,会跟着一个dup指令,为什么呢?

正文

首先来看下这些指令的定义

new 创建一个指定类型的对象,在堆上分配内存,并给该实例的实例字段进行初始化成默认值,再将对象引用的指针压入栈顶。注意:这里并没有调用构造函数进行初始化

dup 从栈顶复制一个值,将复制的值重新压入栈顶

invokespecial 初始化一个对象,而这个对象是从操作栈顶获取

因为在方法里还 test1 变量来承接 new出来的对象,所以在调用invokespecial 时,需要有一个实例对象的引用传给invokespecial ,所以需要dup 从new 出来的对象里复制一个出来。

以下为各个指令执行的操作栈的过程(0-8)

结论

当在代码中使用new这个操作时,其实是分成几个步骤在处理这个对象的

通过指令new 进行分配内存,并初始化实例字段的默认值,如值类型为0, 引用类型为null,这里会生成一个引用复制一个引用出来供构造函数调用传入,进行初始化再将对应的引用值存入局部变量

标签: #java里面new什么意思