单例设计模式,静态访问非静态?

13z8s7eq  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(377)

我认为一个常见的单例设计模式:

public class Singleton{

   private static Singleton instance;

   private Singleton(){}

   public static Singleton getInstance(){

    if(instance==null)
       instance=new Singleton();

   return instance;

   }
}

据我所知,构造函数是非静态方法,因为它们可以使用上下文引用“this”(这在静态上下文中是禁止的)。另一方面,静态成员只能访问静态成员。
那么,静态成员getinstance()如何访问非静态成员构造函数呢?

yks3o0rb

yks3o0rb1#

当你看到一个像 new Singleton() 你必须区分 new 运算符,或者更准确地说是初始化器代码。
这个 new 运算符“像”静态方法调用。它不需要对象的示例,因为它创建了一个示例。
构造函数代码更像一个示例方法,只是它没有返回类型。但它可以访问 this 参考文献。
至少,当您深入研究生成的字节码时,您会看到不同之处。这个 new 运算符将导致此字节码指令。

NEW yourpackage/Singleton

此指令仅在内存中创建对象。请参见jvms-6.5.new
创建对象后,通过执行初始值设定项代码对其进行初始化。在字节码中,它看起来像:

INVOKESPECIAL yourpackage/Singleton.<init> ()V

初始值设定项代码不仅仅是构造函数代码。它调用超类的初始化器并初始化示例字段。
另请参见java虚拟机规范2.9
在java虚拟机级别,每个构造函数都是用java编程语言(jls)编写的§8.8)显示为具有特殊名称的示例初始化方法。此名称由编译器提供。因为名称不是有效的标识符,所以不能直接在用java编程语言编写的程序中使用。示例初始化方法只能由invokespecial指令在java虚拟机中调用(§它们只能在未初始化的类示例上调用。示例初始化方法具有访问权限(jls)§6.6)的构造

ycggw6v2

ycggw6v22#

构造函数不是方法。静态方法与类相关联,非静态方法与该类的示例相关联。不能从静态方法调用非静态方法,因为没有与该静态方法关联的示例。可以从静态方法调用构造函数,因为构造函数与类而不是示例相关联。
构造函数只能在示例化对象之后,即调用构造函数之后,才可以使用“this”引用。

相关问题