这是一个描述我的问题的简化类:
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
。
是的。这是一个编译错误。
不。没有特殊的语法来处理这个问题。
我不想在方法中捕获异常。
不幸的是,如果你抛出一个已检查的异常,它必须被捕获在调用堆栈的更上方。这是 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 运行时完全忽略抛出的异常,那就太糟糕了。:
ExceptionInInitializerError
。此外,JVM 会将
enum
类标记为不可初始化,并且如果您的应用程序将抛出 NoClassDefFoundError
尝试使用它;例如通过 Class.forName(...)
。)
我假设此处使用 Exception
是为了说明目的。将方法声明为
throws Exception
或 throw new Exception(...)
是一件坏事
Exception
)。原因是:您正在
method
的构造函数内部调用 Test
。确实没有一个干净的方法来处理它。虽然这里明显的选择是切换到
RuntimeException
,但我希望您首先重新考虑抛出异常。由于您的枚举只会在其中声明
First
,因此当它被实例化时抛出异常是否真的有意义吗?就我个人而言,我不这么认为;无论它正在执行什么危险的操作,都应该推迟到您想要调用它为止,然后然后您是否想抛出异常。