Java 单例与例外

Java 单例与例外,java,exception,singleton,Java,Exception,Singleton,设计可能引发异常的单例类的最佳方法是什么 这里我有一个Singleton(使用Bill Pugh的方法,记录在Wiki for Singleton中) 如果在2抛出异常,我希望将其传播给调用方。 但是,我不能从第1行抛出异常 那么,如果没有正确创建singleton对象,我唯一可以返回null对象的选项是什么 谢谢 另外,我确实意识到,如果通过不同的类加载器加载,或者如果反射性地加载,那么这个单例可以被破坏,但是对于我的目的来说,它已经足够好了 //更新 我很好奇,我能不能重新安排我的设计如下抛

设计可能引发异常的单例类的最佳方法是什么

这里我有一个Singleton(使用Bill Pugh的方法,记录在Wiki for Singleton中)

如果在2抛出异常,我希望将其传播给调用方。 但是,我不能从第1行抛出异常

那么,如果没有正确创建singleton对象,我唯一可以返回null对象的选项是什么

谢谢

另外,我确实意识到,如果通过不同的类加载器加载,或者如果反射性地加载,那么这个单例可以被破坏,但是对于我的目的来说,它已经足够好了

//更新

我很好奇,我能不能重新安排我的设计如下抛出异常

而且,我不需要任何同步(classloader保证静态内部类只会在调用getInstance()时加载一次)。因此,线程安全和延迟实例化

 private static class SingletonObjectFactoryHolder{
        //1  
           public static ObjectFactory getInstance() throws Exception{
         return new ObjectFactory();
           }
 }

 private ObjectFactory() throws Exception{
        //2
        //create the factory
 }


 public static ObjectFactory getInstance(){
        //3
    return SingletonObjectFactoryHolder.getInstance();
 }

再次感谢。

只是不要从对象的构造函数中抛出异常。您可以提供
init()
方法,并在必要时从那里抛出您的异常。

您可以检查getInstance内部的null实例,并延迟初始化它。但是如果构造函数不抛出,通常是最好的,如果你能使构造函数更安全,那可能是最好的。

我同意Arne Burmeister的观点,代码如下所示:

private static class SingletonObjectFactoryHolder
{
    private static ObjectFactory INSTANCE;


    private ObjectFactory() 
    {

    }

    public static String getInstance() throws Exception
    {
      return (INSTANCE == null) ? (INSTANCE = new ObjectFactory()) : INSTANCE; 
     // A ternary operator might not be the best fit if you need to throw an exception, but I think it looks nicer than the if(INSTANCE==null){} else{} for lazy instantiation.
    }

}

使用静态初始值设定项并将异常重新显示为。单击链接阅读Javadoc,您将看到它完全适合这个特定的功能需求:在静态初始化期间处理异常。事实上,单例只不过是一个静态和延迟初始化的全局对象

private static class SingletonObjectFactoryHolder{
    private static final ObjectFactory INSTANCE;
    static {
        try {
            INSTANCE = new ObjectFactory();
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}

不需要被视为反模式的习语,在某些情况下甚至是不安全的。

BalusC的回答是正确的,但也请参见“谢谢”。尽管抛出一个错误确实有点不寻常。:)@finnw更新版本的链接:@BalusC在私有构造函数中创建实例并在那里处理异常不是更容易吗?@oldergod:我想知道您打算如何在实例的构造函数中创建实例,而不陷入无限循环创建多个实例——违反单例模式。此外,OP明确提到使用比尔·普格的方法,因此我继续使用该方法。@BalusC我在本页上参考了示例1※我错过了OP要求使用比尔·普格方法的部分。
private static class SingletonObjectFactoryHolder{
    private static final ObjectFactory INSTANCE;
    static {
        try {
            INSTANCE = new ObjectFactory();
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}