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

时间:2016-03-28 12:02:44

标签: java design-patterns singleton

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

public class Singleton{

   private static Singleton instance;

   private Singleton(){}

   public static Singleton getInstance(){

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

   return instance;

   }
}

据我所知,costructors是非静态方法,因为它们可以使用上下文引用“this”(静态上下文中禁止)。另一方面,静态成员只能访问静态成员。

那么静态成员getInstance()如何访问非静态成员构造函数呢?

2 个答案:

答案 0 :(得分:4)

当您看到像new Singleton()这样的对象创建时,您必须将new运算符与构造函数代码区分开来,或者更准确地说明初始化代码。

new运算符是“ like ”静态方法调用。它不需要对象的实例,因为它会创建一个。

构造函数代码更像是“ like ”一个实例方法,除了它没有返回类型。但它可以访问this引用。

当您深入了解生成的字节码时,至少会看到不同之处。 new运算符将导致此字节码指令。

NEW yourpackage/Singleton

该指令仅在内存中创建对象。见jvms-6.5.new

创建对象后,通过执行初始化代码初始化它。在字节码中它看起来像:

INVOKESPECIAL yourpackage/Singleton.<init> ()V 

初始化代码不仅仅是构造函数代码。它调用超类的初始化程序并初始化实例字段。

另见java virtual machine specification 2.9

  

在Java虚拟机级别,使用Java编程语言(JLS§8.8)编写的每个构造函数都显示为具有特殊名称的实例初始化方法。该名称由编译器提供。因为名称不是有效的标识符,所以它不能直接用在用Java编程语言编写的程序中。实例初始化方法只能通过invokespecial指令(§invokespecial)在Java虚拟机中调用,并且它们只能在未初始化的类实例上调用。实例初始化方法接受从中派生的构造函数的访问权限(JLS§6.6)

答案 1 :(得分:1)

构造函数不是方法。静态方法与类关联,非静态方法与该类的实例关联。您不能从静态方法调用非静态方法,因为没有与静态方法关联的实例。您可以从静态方法调用构造函数,因为构造函数与类相关联,而不是与实例相关联。

构造函数可以使用&#34;这个&#34;仅在实例化对象之后,即在调用构造函数之后引用。