| 失效链接处理 | 
| 
      《剑指offer》Java创建对象的五种方式 PDF 下载 
	相关截图: 
![]() 主要内容: 
		使用 new 来创建对象 
	
		使用 new 来创建对象是最简单的一种方式了, new 是 Java 中的关键字,new 通过为新对象分配内存 
	
		并返回对该内存的引用来实例化一个类,这个实例化一个类其实就相当于创建了一个对象,因为类也是 
	
		一种对象;new 也负责调用对象的构造函数,下面是使用 new 来创建对象的代码 
	
		Object obj = new Object(); 
	
		这段代码中,我们在堆区域中分配了一块内存,然后把 obj 对象指向了这块内存区域。 
	
		不知道你有没有看过 new 的字节码呢?下面是这段代码的字节码 
	
		在 Java 中,我们认为创建一个对象就是调用其构造方法,所以我们使用 new Object() 构造的对象,其 
	
		实是调用了 Object 类的 无参数 的构造方法。但是通过字节码我们发现,对象的创建和调用其构造方法是分开的。 
	
		字节码的 new 表示在堆中创建一个对象,并把对象的引用推入栈中。 invokespecial 表示调用对象无 
	
		参数的构造方法。其实,JVM 提供了五种方法调用指令,分别是 
	
		invokestatic :该指令用于调用静态方法,即使用 static 关键字修饰的方法; 
	
		invokespecial :该指令用于三种场景:调用实例构造方法,调用私有方法(即 private 关键字修饰 
	
		的方法)和父类方法(即 super 关键字调用的方法); 
	
		invokeinterface :该指令用于调用接口方法,在运行时再确定一个实现此接口的对象; 
	
		invokevirtual :该指令用于调用虚方法(就是除了上述三种情况之外的方法); 
	
		invokedynamic :在运行时动态解析出调用点限定符所引用的方法之后,调用该方法;在 JDK 1.7 
	
		中提出,主要用于支持 JVM 上的动态脚本语言(如 Groovy,Jython 等) 
	
		好了,现在你知道了 new 和 invokespecial 是干啥用的,那么 dup 指令呢? 
	
		dup 会复制栈上的最后一个元素,然后再次将其推入栈;因此,如果在栈上有一个对象引用,并且调用 
	
		了 dup,则现在在栈上有对该对象的两个引用。看起来有点不知其所以然,所以在求助网上的时候,又 
	
		发现了 R 大的解释 
	
		来源:./images/52749416 
	
		后面的 astore 就会把操作数栈顶的那个引用消耗掉,保存到指定的局部变量去。 
	
		如果直接使用 new Object() 没有创建局部变量的话,请注意一下它的字节码。 
	
		看出来细微的差别了吗?上图中的 astore_1 竟然变成了 pop ,这也就是说,new Object() 没有保存对 
	
		象的局部变量,而是直接把它给消耗掉了。嗯,符合预期。 
	
		所以这是第一种创建的方式,也就是使用 new 来创建。 
	 | 
    




    
苏公网安备 32061202001004号


    