这个方法给了我一个汇编,我不明白为什么:
private void invokeMethods(Object instance, List<Method> methods)
throws InvocationTargetException, IllegalAccessException {
methods.forEach(method -> method.invoke(instance));
}
错误消息是:
未报告的异常java.lang.IllegalAccessException;必须抓住 或宣布被抛出
这没有意义:已经宣布异常被抛出。
IntelliJ也无法纠正它。在意图操作中,如果我选择为方法签名添加例外,它就什么都不做。
我错过了什么? (我是Java 8的新手)
答案 0 :(得分:13)
这里的问题是抛出异常的 lambda ,并且forEach
中使用的lambda未声明抛出异常。请参阅Consumer文档。
解决这个问题的最佳方法是使用老式的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
中,这不是很好...... < / p>
IntelliJ也无法纠正它。在意图操作中,如果我选择“向方法签名添加例外”,则不会执行任何操作。
IntelliJ无法做到这一点的原因是因为它是Consumer
接口的一部分,它是JDK的一部分。 IntelliJ没有办法修改它。当然,IntelliJ可以更好地处理这个问题。
有时候,lambdas很有用,有时旧的做事方式会更好。
答案 1 :(得分:0)
(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);
}