为什么java.lang.ExceptionInInitializerError都没有带有消息和原因的构造函数?

时间:2013-05-07 02:31:08

标签: java exception static initialization

我使用java.lang.ExceptionInInitializerError重新抛出静态初始化块中捕获的异常。我注意到不可能同时构建消息和原因;只有一个或另一个。

  1. 有充分的理由吗?
  2. 您可以建议将已检查的异常重新抛出为静态初始化块的未经检查的异常吗?例如:Rethrow为java.lang.RuntimeException,允许消息和原因。
  3. 更新:澄清了#2并添加了示例代码。

    public class Sample {
    
        private static final String _FILE_PATH = "blah/blah/blah";
    
        static {
            try {
                FileReader in = new FileReader(new File(_FILE_PATH));
            }
            catch (FileNotFoundException e) {
                // Option A: Without context message
                throw new ExceptionInInitializerError(e);
                // Option B: With context message
                String msg = String.format("Failed to open file for reading: '%s'", _FILE_PATH);
                throw new RuntimeException(msg, e);
            }
        }
    }
    

    参考:Why doesn't Java allow to throw a checked exception from static initialization block?

3 个答案:

答案 0 :(得分:1)

正如文档here所示,有一个构造函数ExceptionInInitializerError(Throwable thrown),您可能应该使用它:它符合标准异常链,它保留了堆栈跟踪并执行其他有用的操作(请参阅{{ 3}})。

修改

a sample chained-exception output中所述,您链接到的问题是:禁止将已检查的异常从static块中删除;未经检查的异常很好,但无法在任何地方捕获,除非有人使用Class.forName进行手动动态类加载(非常不常见)。

这转化为“祝你在静态初始化器中捕获任何东西”。基本上,无论你构造和抛出什么异常,它都没有多大用处。

答案 1 :(得分:1)

您希望同时使用消息(您编写的)和异常本身抛出异常。我喜欢这样做,为错误和异常提供上下文。我会抛出一个Exception(或扩展Exception或子类的Exception类的实例),而不是RuntimeException,因为您可能希望检查异常。正确?

一般来说,如果系统无法从异常和运行时异常(未选中)恢复(在更高级别)系统,则应该抛出已检查的激活。 (James Gosling的观点)

答案 2 :(得分:0)

这是一个错误。通常,错误是应用程序甚至不应该尝试捕获和恢复的错误。

至于为什么它没有带有消息和原因的构造函数,可能是因为该类的开发人员认为没必要,因为该类的主要目的是让你知道“oops shit发生了兄弟,无法恢复......“

我个人认为其中一个足以识别错误。