在同一个 catch 子句中编译错误捕获异常

Compile error catching exceptions in the same catch clause

我有两个 RuntimeExceptions,如下所示:

@Getter
@RequiredArgsConstructor
public class MyCustomRuntimeException1 extends RuntimeException {

    private final String message;
    private final int code;
}

@Getter
@RequiredArgsConstructor
public class MyCustomRuntimeException2 extends RuntimeException {

    private final String message;
    private final int code;
}

然后我有我的 doSomethingMethod,我在同一个 catch 子句中捕获它们:

public void doSomething() {

[....]
[....]
 
    try {

         [....]
         [....]    

    } catch (MyCustomRuntimeException1 | MyCustomRuntimeException2 ex) {
            log.error("!! doSomething: An error occurred", ex);
            var code = ex.getCode();
            var message = ex.getMessage();

            [......]
            [......]
    }
}

我收到编译时错误,在以下行显示 Cannot resolve method 'getCode' in 'RuntimeException'

var code = ex.getCode();

另一方面,这段代码可以正常工作:

public void doSomething() {

[....]
[....]
 
    try {

         [....]
         [....]    

    } catch (MyCustomRuntimeException1 ex) {
            log.error("!! doSomething: An error occurred", ex);
            var code = ex.getCode();
            var message = ex.getMessage();

            [......]
            [......]

    } catch (MyCustomRuntimeException2 ex) {
            log.error("!! doSomething: An error occurred", ex);
            var code = ex.getCode();
            var message = ex.getMessage();

            [......]
            [......]
    }
}

由于您要扩展 MyCustomRuntimeException1 和 MyCustomRuntimeException2 中都存在的 getCode() 方法,编译器会混淆您要指向哪个运行时异常 getCode()? .

要解决此问题,您可以

i) 指定 class 名称和您尝试调用的方法。

我相信这里发生的事情是,当你有一个 multi-catch 子句时,异常参数的推断类型,在你的情况下 ex,是最接近的常见 superclass中列出的异常multi-catch。我在语言参考中找不到这个明确的记录,但至少在一个地方暗示了这一点。请参阅 14.20. the try statement

末尾的示例

所以你的两个异常 classes 中最接近的公共 superclass 是 RuntimeException,它当然没有 getCode() 方法。

正如@VasilyLiakovsky 在评论中建议的那样,您可以创建一个抽象中间体 class 来定义您想要共享的常用方法。