单例和异常

2022-09-01 12:05:39

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

在这里,我有一个辛格尔顿(使用比尔·皮尤的方法,记录在单例的Wiki中)。

    private static class SingletonObjectFactoryHolder{
    //1  
        private static final ObjectFactory INSTANCE = new ObjectFactory();
    }

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


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

如果在2处引发异常,我想将其传播给调用方。但是,我不能从第 1 行引发异常。

那么,如果单例对象创建不正确,我唯一的选择是返回空对象吗?

谢谢

P.S 我确实意识到,如果它通过不同的类加载器加载或者条件反射地加载,这个Singleton可能会中断,但它对于我的目的来说已经足够好了。

更新

我很好奇,我能不能像下面那样重新排列我的设计以抛出异常?

另外,我不需要任何同步(类装入器保证静态内部类只会加载一次,并且仅在调用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();
 }

再次感谢。


答案 1

使用静态初始值设定项并将 重新命名为 ExceptionInitializerError。单击链接以阅读Javadoc,您将看到它完全适合此特定功能要求:在静态初始化期间处理异常。实际上,单例只不过是静态和懒惰初始化的全局对象。Exception

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

不需要双重检查锁定成语,这被认为是一种反模式,在某些情况下甚至不安全。


答案 2

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