Java 私有构造函数和实例-多选

Java 私有构造函数和实例-多选,java,singleton,Java,Singleton,我试图找出以下问题的答案。我试着在谷歌上寻找答案,但人们对这个问题似乎有不同的答案。有人能解释一下他们的答案吗 public class Gingleton { private static Gingleton INSTANCE = null; public static Gingleton getInstance() { if ( INSTANCE == null ) { INSTANCE = new Gingl

我试图找出以下问题的答案。我试着在谷歌上寻找答案,但人们对这个问题似乎有不同的答案。有人能解释一下他们的答案吗

public class Gingleton {
    private static Gingleton INSTANCE = null;

    public static Gingleton getInstance()
    {
        if ( INSTANCE == null )
        {
            INSTANCE = new Gingleton();
        }
        return INSTANCE;
    }

    private Gingleton() {
    }
}
  • 可以创建多个Gingleton实例(我的选择)

  • 金格尔顿永远不会被创造出来

  • 构造函数是私有的,无法调用

  • 值可以被垃圾收集,并且对getInstance的调用可能会 返回垃圾数据


getInstance()
中创建新实例时不会以任何方式同步,因此可能会在多线程环境中创建多个实例。要确保只有一个实例,您应该执行以下操作:

public class Gingleton {

    // volatile
    private static volatile Gingleton INSTANCE = null;

    public static Gingleton getInstance()
    {
        if ( INSTANCE == null )
        {
            synchronized (Gingleton.class) {  // Synchronized
                if ( INSTANCE == null )
                {
                    INSTANCE = new Gingleton();
                }
            }
        }
        return INSTANCE;
    }

    private Gingleton() {
    }
}
如果出现某种竞争条件,可能会(可能是意外地)创建多个实例(每个JVM)

这段代码实际上反映了一种“惰性单例模式”,即每个JVM只有一个实例,在第一次访问它时创建

=>乍一看,我们只能有一个实例。但是,由于代码不同步,这部分代码可能会在多线程环境中并行执行多次

if ( INSTANCE == null )
    {
        INSTANCE = new Gingleton();
    }
另请参见此处的评论

所以我会说这是一个糟糕的问题,你可以在头上猛击MC作者,因为:

  • 可以创建多个Gingleton实例(我的选择)
=>考虑到上面的讨论,这是正确的,但这可能不是问题作者的想法

  • 金格尔顿永远不会被创造出来
=>errr,嗯,
getInstance()
在这个代码段中从未被调用=>nope,没有创建实例。但作者可能认为我们可以称之为这种方法,在这种情况下,答案是肯定的

  • 构造函数是私有的,无法调用
可以调用私有构造函数。。。只是不在课堂之外。同样,作者并没有阐述它,但我们可以假设他或她只是从“外部”考虑这个案件

  • 值可以被垃圾收集,对getInstance的调用可能会返回垃圾数据

啊,这个说法至少是清楚的。不,静态字段不会被垃圾收集,您可以依赖它的值

你可以很容易地运行一个测试,看看你的答案是否正确。
Gingleton的+1:)“我认为这是正确的,因为构造函数是私有的”——很可能不是正确的推理。如何创建两个或多个实例?(你的回答)@LutzHorn不,我想只有一个是正确的。我给了你+1,因为我指出了选项的荒谬性。很难说出预期的“正确”答案是什么。我想指出,
getInstance()
从未被调用只是被调用pedantic@Radiodef谢谢阅读考官的思想确实是一门微妙的艺术:)。我个人会猜到3,这个问题和多答案感觉就像我们开始学习java时遇到的那种情况,所以在这个类的上下文中,多线程可能超出了范围,重点是强调方法访问修饰符的用法。@Deachex,好吧,我想你是对的。然而,我仍然感到很沮丧,因为我不得不猜测考试时预期的严格程度。@Svend我仍然在反复思考我认为预期答案是什么。我也开始提到#3,因为我认为这个问题应该在访问修饰符上测试。这是唯一一种看待它并使它整体上有意义的方法。回答得好,你能补充一点说明为什么需要
volatile
,为什么需要两个空检查。@Rembo