我使用java.lang.ExceptionInInitializerError
重新抛出静态初始化块中捕获的异常。我注意到不可能同时构建消息和原因;只有一个或另一个。
java.lang.RuntimeException
,允许消息和原因。更新:澄清了#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?
答案 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发生了兄弟,无法恢复......“
我个人认为其中一个足以识别错误。