编译由于未声明异常而失败,即使已声明异常也是如此



这个方法给了我一个编译,我不明白为什么:

private void invokeMethods(Object instance, List<Method> methods)
        throws InvocationTargetException, IllegalAccessException {
    methods.forEach(method -> method.invoke(instance));
}

错误消息是:

未报告的异常 java.lang.IllegalAccessException; 必须捕获 或宣布被抛出

这没有意义:异常已经声明为抛出。

IntelliJ也无法纠正它。在意向操作中,如果我选择"向方法签名添加例外",则它不执行任何操作。

我错过了什么?(我是Java 8的新手(

这里的问题是抛出异常的是 lambda,而 forEach 中使用的 lambda 没有声明为抛出异常。请参阅使用者文档。

解决这个问题的最好方法实际上是使用老式的 for-each 循环:

for (Method method : methods) {
    method.invoke(instance);
}

虽然可以使用这样的东西:

methods.forEach(method -> {
        try {
            method.invoke(instance);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
});

在我看来,它并没有真正帮助你,因为你不能再从 lambda 中抛出完全相同的异常,你必须把它包装在一个RuntimeException中,这并不好......

IntelliJ也无法纠正它。在意向操作中,如果我选择"向方法签名添加例外",则它不执行任何操作。

IntelliJ 无法做到这一点的原因是因为它是 Consumer 接口的一部分,而 接口是 JDK 的一部分。IntelliJ没有办法修改它。当然,IntelliJ可以以更好的方式处理这个问题。

结论:

有时 lambda 很有用,有时旧的做事方式更好。

(method -> method.invoke(instance))是lambda表达式并且这个表达式可以抛出IllegalAccessException | InvocationTargetException,可以在try/catch内将其包围

   methods.forEach(method -> {
            try {
                method.invoke(instance);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace(); // or throw new RuntimeException(e);
            }
        });

如果您不想在 lambda 中处理异常,则只需使用

for (Method method : methods) {
        method.invoke(method);
    }

相关内容

  • 没有找到相关文章

最新更新