This method gives me a compilation and I don't understand why:
private void invokeMethods(Object instance, List<Method> methods)
throws InvocationTargetException, IllegalAccessException {
methods.forEach(method -> method.invoke(instance));
}
The error message is:
unreported exception java.lang.IllegalAccessException; must be caught or declared to be thrown
Which doesn't make sense: the exception is already declared to be thrown.
IntelliJ cannot correct it either. In intention actions if I select Add Exceptions to Method Signature, it does nothing.
What am I missing? (I'm new to Java 8)
The problem here is that it is the lambda that throws the exception, and the lambda used in forEach
is not declared to throw an Exception. See Consumer documentation.
The best way to solve this is really to use the old-fashioned for-each loop:
for (Method method : methods) {
method.invoke(instance);
}
Although it is possible to use something like this:
methods.forEach(method -> {
try {
method.invoke(instance);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
});
It doesn't really help you in my opinion because you can't throw the exact same exception from the lambda anymore, you have to wrap it in an RuntimeException
, which is not as nice...
IntelliJ cannot correct it either. In intention actions if I select Add Exceptions to Method Signature, it does nothing.
The reason why IntelliJ cannot do that is because it's part of the Consumer
interface, which is part of the JDK. IntelliJ does not have a way to modify that. IntelliJ could handle this in a better way though, of course.
There are times when lambdas are useful, and there are times when the old ways of doing things is better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With