当前位置: 首页 > 知识库问答 >
问题:

构造函数可能抛出检查异常时如何实现单例

况博容
2023-03-14
public class Class1Exception extends Exception {
   ...
}

我有一个名为Class1的类,它的构造函数可能会抛出Class1Exception

public class Class1 {
   public Class1() throws Class1Exception {
      ...
   }
   ...
}

现在我想为类class1实现线程安全的单例模式。通常,我通过将构造函数私有化来实现单例,创建一个与class类型相同的静态final变量,该变量也调用构造函数,然后使用getInstance方法来访问它:

public class Class1 {
   private static final Class1 INSTANCE = new Class1();

   private Class1() throws Class1Exception {
      ...
   }

   public static Class1 getInstance() throws Class1Exception {
      return INSTANCE;
   }
}

问题是这种解决方案在这种情况下不起作用,因为构造函数抛出了一个检查异常。将checked exception更改为unchecked不是选项。解决办法是什么?

澄清一下:类class1不能自己处理class1exception。此异常应由调用class1的任何代码处理。

谢谢

共有1个答案

任小云
2023-03-14

一种解决方案是采用两阶段建设:

  1. 创建实例
  2. 继续可能引发的构造

调用者在第二次调用Instance()之前处理任何异常(例如在finally块中)。因为类对象是在第1阶段的早期成功创建的,所以这个后续调用现在能够返回一个有效的实例。当然,第二阶段的构造还没有完成,但是调用者确实通过异常机制知道了这一点。

private static volatile Class1 _instance = null;
private static readonly object _sync = new object();

public static Class1 Instance()
{
    if (_instance == null)
    {
        lock (_sync)
        {
            if (_instance == null)
            {
                _instance = new Class1();

                _instance.Init(); // can throw
            }
        }
    }

    return _instance;
}

private class Caller
{
    Class1 _class1;

    private void LoadClass1()
    {
        try
        {
            _class1 = Class1.Instance();
        }
        catch (Exception ex)
        {
            // handle exception
        }
        finally
        {
            _class1 = Class1.Instance();
        }
    }
}
 类似资料:
  • 问题内容: 是否有关于对象是否使用异常的构造函数清除的详细信息。 众所周知,定义此方法的时间很短。根据手册: Java编程语言不能保证哪个线程将为任何给定对象调用finalize方法。但是,可以保证,调用finalize的线程在调用finalize时不会持有任何用户可见的同步锁。如果finalize方法抛出未捕获的异常,则该异常将被忽略,并且该对象的终止将终止。 http://docs.oracl

  • 这是主要的方法: 运行时,这是堆栈跟踪:

  • 我有一个异步函数,我希望在失败时抛出异常。然而,似乎有一些东西阻止了这一点: 通过省略try catch块,我希望抛出一个异常,我想在函数外部处理这个异常。 我得到的实际结果有点令人困惑: 当我尝试捕获异常并抛出其他东西时,会得到相同的结果: 该函数是从try块调用的,因此看不到这如何是未处理的promise。 我正在尝试使用< code>f作为另一个函数的参数:

  • 我正在将应用程序迁移到最新的spring boot版本(使用gradle spring boot dependencies和2.5.4版)。 我有一个名为的实体,它用注释;以及另一个实体,用注释。Customer类有

  • 无参数构造函数抛出一个不可能的异常还是有一个空的catch块更好?比如说我有一门这样的课。 编译器强制构造函数要么抛出NumberFormatException(这永远不会发生),要么使用try/catch块。然而,有一个空的挡块是正确的吗?这通常是不受欢迎的? 请注意,Foo将是一个库类,其他人也会使用它,所以让一个无参数构造函数抛出一个不可能的异常会让人困惑。还要注意,真正的异常是一个自定义异

  • 假设我想在收到特定异常时恢复某个值,否则返回失败的未来。我希望是这样的: 如果函数会抛出检查过的异常,我想在链式方法中处理它。我尝试过和,但都无法编译。是否为这种情况提供了任何解决方案?我知道接口是方法的参数,它不会抛出任何异常——在这种情况下,我只想返回已经失败的未来。我想找到使用Java8的解决方案。