【问题标题】:Singleton design pattern, static access non static?单例设计模式,静态访问非静态?
【发布时间】:2016-03-28 20:50:43
【问题描述】:

我想到了一个常见的单例设计模式:

public class Singleton{

   private static Singleton instance;

   private Singleton(){}

   public static Singleton getInstance(){

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

   return instance;

   }
}

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

那么静态成员getInstance()怎么可能访问非静态成员构造函数呢?

【问题讨论】:

  • 可以从任何地方调用构造函数。(这里,因为它是单例的——所以在类内部的任何地方)
  • 这里创建了一个新实例。这不像我们在您的静态方法中调用Singleton()(就像我们调用另一个方法一样)。这当然是不可能的。
  • costructors 是非静态方法。构造函数是构造函数。方法有一个返回类型。

标签: java design-patterns singleton


【解决方案1】:

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

new 运算符是“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 编程语言编写的程序中使用。实例初始化方法只能在 Java 虚拟机中通过 invokespecial 指令(§invokespecial)调用,并且只能在未初始化的类实例上调用。实例初始化方法具有派生它的构造函数的访问权限(JLS §6.6)

【讨论】:

    【解决方案2】:

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

    构造函数只能在对象被实例化后使用“this”引用,即在构造函数被调用之后。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 2012-03-30
      相关资源
      最近更新 更多