当前位置: 首页 > 面试题库 >

单例和例外

满和安
2023-03-14
问题内容

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

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

    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行引发异常。

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

谢谢

PS我确实意识到,如果该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();
 }

再次感谢。


问题答案:

使用静态初始值设定项,然后将Exceptionas
扔掉ExceptionInInitializerError。单击链接以阅读Javadoc,您将看到它完全适合此特定功能要求:在
静态初始化 期间处理异常。实际上,单例仅仅是静态和延迟初始化的全局对象。

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

不需要双重检查的锁定习惯,这是一种反模式,在某些情况下甚至是不安全的。



 类似资料:
  • 按照我们在Java中一样创建一个单例最简单的方式: class App : Application() { companion object { private var instance: Application? = null fun instance() = instance!! } override fun onCreate() {

  • 本文向大家介绍Javascript单例模式的介绍和实例,包括了Javascript单例模式的介绍和实例的使用技巧和注意事项,需要的朋友参考一下 前言 其实和其他编程语言一样,Javascript同样拥有着很多种设计模式,比如单例模式、代理模式、观察者模式等,熟练运用Javascript的设计模式可以使我们的代码逻辑更加清晰,并且更加易于维护和重构。 本文将会介绍Javascript中的单例模式,在

  • 我试图学习Guice,但下面的场景似乎很难。假设我有A、B和C类。我应该能够做到以下几点(注意,这个例子在某种程度上简化为实际情况): A是全球单身人士 当B创建C时,C的依赖项B必须是相同的实例,即从C的角度来看,B是单例的。 我尝试过创建儿童注射器: } 但是Guice给出了B已经绑定的错误(MainModule中提供了方法)。因此,我需要覆盖MainModule的B绑定,但这似乎不可能使用子

  • 问题内容: 我正在学习Spring框架,目前正在阅读有关它的书。在这本书中,它说Spring单例与Java单例不同吗?这是什么意思,有什么区别?谢谢 问题答案: Java单例由Java类加载器确定范围,Spring单例由容器上下文确定范围。 从根本上讲,这意味着在Java中,可以确保单例仅在加载它的类加载器的上下文中才是真正的单例。尽管您在代码中尽力防止它发生,但其他类加载器也应该能够创建它的另一

  • 引用test.nsi的内容: ;Sendmessage简单例子 ;WWW.Dreams8.CoM ; !include "WinMessages.nsh" !include "LogicLib.nsh" name "Sendmessage简单例子" outfile "test.exe" page custom show leave reservefile "pagecustom.ini"

  • 单例准备好的语句会比每次创建一个语句更好吗?