我认为是一个常见的单例设计模式:
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null)
instance=new Singleton();
return instance;
}
}
据我所知,costructors是非静态方法,因为它们可以使用上下文引用“this”(静态上下文中禁止)。另一方面,静态成员只能访问静态成员。
那么静态成员getInstance()如何访问非静态成员构造函数呢?
答案 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;仅在实例化对象之后,即在调用构造函数之后引用。