由于未声明异常,编译失败,即使它已声明

Sto*_*ica 6 java java-8

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

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

错误消息是:

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

这没有意义:已经宣布异常被抛出.

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

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

Sim*_*erg 14

这里的问题是它抛出异常是lambda,并且forEach没有声明使用的lambda 抛出异常.请参阅消费者文档

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

for (Method method : methods) {
    method.invoke(instance);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

结论:

有时候lambdas是有用的,有时旧的做事方式更好.