未处理的异常类型Exception

问题描述 投票:0回答:2

这是一个描述我的问题的简化类:

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 exception enums
2个回答
7
投票

是的。这是一个编译错误。

不。没有特殊的语法来处理这个问题。

我不想在方法中捕获异常。

不幸的是,如果你抛出一个已检查的异常,它必须被捕获在调用堆栈的更上方。这是 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 运行时崩溃,那么检查异常的模型就会被破坏。
  • 所以,这对我来说是,Java 语言设计是正确的,Java 编译器是正确的......而这里真正的问题在于您的应用程序
设计

    您不应该在此处传播已检查的异常。如果在此上下文中发生异常,那么它绝对不是可恢复的错误。
  • 也许为此使用枚举是不明智的……因为可能会出现不可恢复的初始化错误。
  • (请注意,如果此方法调用由于未经检查的异常而终止,则会将其变成
ExceptionInInitializerError

。此外,JVM 会将

enum
类标记为不可初始化,并且如果您的应用程序将抛出
NoClassDefFoundError
尝试使用它;例如通过
Class.forName(...)
。)

我假设此处使用
Exception

是为了说明目的。将方法声明为

throws Exception
throw new Exception(...)
 是一件坏事


1 - 我查看了 JLS,寻找支持这一点的东西。据我所知,规范中没有提到这种情况。我本来希望看到它列在

JLS 11.2.3 中。然而,很明显,编译器不能允许检查异常在此时传播,因为它会“破坏”检查异常工作的模型。


1
投票
Exception

)。原因是:您正在

method
的构造函数内部调用
Test
。确实没有一个干净的方法来处理它。

虽然这里明显的选择是切换到

RuntimeException

,但我希望您首先重新考虑抛出异常。由于您的枚举只会在其中声明

First
,因此当它被
实例化
时抛出异常是否真的有意义吗?就我个人而言,我不这么认为;无论它正在执行什么危险的操作,都应该推迟到您想要调用它为止,然后然后您是否想抛出异常。

© www.soinside.com 2019 - 2024. All rights reserved.