这是一个描述我的问题的简化类:
public class Main {
enum Test{
First(method()){ // Unhandled exception type Exception
// ...
};
Test(Object obj){
//...
}
}
static Object method() throws Exception{
// ...
if (someCondition){
throw new Exception();
}
}
}
以上someCondition
取决于设备和某些情况,我现在无法决定,也如您所见,我不想在Exception
中抓住method
。< / p>
答案 0 :(得分:2)
是。这是一个编译错误。
没有。没有特殊的语法来处理这个问题。
我不想在方法中捕获异常。
不幸的是,如果您抛出一个已检查的异常,必须在调用堆栈中进一步捕获。这是Java语言的基本设计原则,也是编译器严格执行的原则。
在这种情况下,无法捕获已检查的异常。因此,如果要在枚举常量参数中调用方法(根据您的代码),该方法不能抛出已检查的异常 1 。
这是一个可能的解决方法,虽然这可能是一个坏主意:
public class Main {
enum Test{
First(methodCatchingException()){
// ...
};
Test(Object obj){
//...
}
}
static Object method() throws Exception{
// ...
if (someCondition){
throw new Exception();
}
}
static Object methodCatchingException() {
try {
return method();
} catch (Exception ex) {
throw new SomeRuntimeException("the sky is falling!", ex);
}
}
}
另一种看待这个问题的方法是问问自己,如果编译器允许你编写那个,那么应该会发生什么?并抛出异常?它会去哪里?
enum
初始化就像static
初始化一样。所以,这对我说的是Java语言设计是正确的,Java编译器是正确的......这里的真正问题在于你的应用程序 design :
您不应在此处传播已检查的例外。如果在此上下文中发生异常,则绝对不是可恢复的错误。
也许不建议使用枚举...因为可能出现不可恢复的初始化错误。
(请注意,如果此方法调用因未经检查的异常而终止,则会将其转换为ExceptionInInitializerError
。此外,JVM会将enum
类标记为无法初始化,并将抛出NoClassDefFoundError
如果您的应用尝试使用它;例如通过Class.forName(...)
。)
我假设此处使用Exception
作为说明目的。将方法声明为throws Exception
或throw new Exception(...)
1 - 我看了一下JLS有什么要支持的。据我所知,该规范没有提到这种情况。我预计会在JLS 11.2.3中看到它列出来。但是,很明显,编译器不能允许已检查的异常在该点传播,因为它会&#34; break&#34;检查异常如何工作的模型。
答案 1 :(得分:1)
我认为你不想在这里抛出一个检查过的异常(这就是Exception
)。原因是:您在method
的构造函数内调用了Test
。真的没有一个干净的方法来处理它。
虽然这里显而易见的选择是切换到RuntimeException
,但我希望您首先重新考虑抛出异常。由于你的枚举只会在其中声明First
,它真的是否有意义在它被实例化时抛出异常?我个人认为不是这样;任何危险的操作都应该推迟到你想要调用它,然后那么你想要抛出异常。