单例设计模式中的Java静态对象范围不会引发空指针异常

时间:2018-07-17 08:38:49

标签: java design-patterns

我在练习单例模式时创建了如下课程:

class Singleton
{
    // static variable single_instance of type Singleton
    private static final Singleton single_instance = new Singleton();

    // private constructor restricted to this class itself
    private Singleton()
    {
        System.out.println("Yahoo");
    }

    // static method to create instance of Singleton class
    public static Singleton getInstance()
    {
        return single_instance;
    }
    public static void getDemo()
    {
        System.out.println("YOHOO");
    }
}

我知道它并不完全正确。但是然后在主类中,我在主函数中这样调用:

package common;

public class TestMain {

    public static void main(String[] args) {
        Singleton tmp = Singleton.getInstance();
        tmp = null;
        System.out.println(tmp);
        tmp.getDemo();

    }

}

这是什么?

Yahoo
null
YOHOO

但是为什么第二次调用getDemo()时没有 null指针异常? 我不确定是否遗漏了任何范围的详细信息,但会感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

通过以类为前缀的静态方法或以类的类型声明的变量访问静态方法将产生相同的结果。
编译器不会评估tmp对象来调用该方法,而是直接调用静态方法。

JLS所述:

  

15.12.4.1。计算目标参考(如有必要)

     

有六种情况要考虑,具体取决于方法的形式   调用:

     
      
  • 如果表单是MethodName-即只是一个标识符-那么:

         
        
    • 如果调用方式是静态的,则没有目标引用。
    •   
  •   

请注意,编译器还应发出以下警告:

  

应访问Singleton类型的静态方法getDemo()   以静态方式

因此,您应该遵循此建议并将其替换为:

Singleton.getDemo();

已编译类的main()方法的反汇编版本显示:

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #16                 // Method common/Singleton.getInstance:()Lcommon/Singleton;
       3: astore_1
       4: aconst_null
       5: astore_1
       6: getstatic     #22                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: aload_1
      10: invokevirtual #28                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      13: invokestatic  #34                 // Method Lcommon/Singleton.getDemo:()V
      16: return
}

答案 1 :(得分:0)

您正在调用的方法是静态方法。它不依赖于指针值。它只是看到引用类型来调用该方法。