I'm working on project with Java 8 and found one situation which I can't understand.
I have code like this:
void deleteEntity(Node node) throws SomeException {
for (ChildNode child: node.getChildren()) {
deleteChild(child);
}
}
void deleteChild(Object child) throws SomeException {
//some code
}
This code is working fine, but I can rewrite it with a method reference:
void deleteEntity(Node node) throws SomeException {
node.getChildren().forEach(this::deleteChild);
}
And this code doesn't compile, giving the error Incompatible thrown types *SomeException* in method reference
.
Also IDEA gave me the error unhandled exception
.
So, my question is why? Why code compiles with for each loop and doesn't compile with lambda?
If you look at the Consumer<T>
interface, the accept
method (which is what your method reference would effectively be using) isn't declared to throw any checked exceptions - therefore you can't use a method reference which is declared to throw a checked exception. The enhanced for loop is okay, because there you're always in a context where SomeException
can be thrown.
You could potentially create a wrapper which converts the checked exception to an unchecked exception, and throw that. Alternatively, you could declare your own functional interface with an accept()
method which does throw a checked exception (probably parameterizing the interface with that exception), and then write your own forEach
method that takes that functional interface as an input.
See more on this question at Stackoverflow