Reputation: 869
Does anyone know why throwing a Throwable or an Exception in a Stream doesn't compile in the code below?
Environment: Win 10 x64, Eclipse 2020-03, openJDK v14
public void myMethod(final boolean myBoolean) throws Throwable {
if (myBoolean) {throw new Exception("Compiler accepts this OK");}
if (myBoolean) {throw new Throwable("Compiler accepts this OK");}
Stream.of("").forEach(s -> {throw new Error("");});
Stream.of("").forEach(s -> {throw new RuntimeException("");});
Stream.of("").forEach(s -> {throw new Exception("Compiler -> Unhandled exception type Exception");});
Stream.of("").forEach(s -> {throw new Throwable("Compiler -> Unhandled exception type Throwable");});
}
I've declared that the Method throws Throwable & outside the Stream it compiles ok, but inside, it seems I can only throw subclasses of Error & RuntimeException.
Upvotes: 0
Views: 991
Reputation: 718788
Short answer is that Exception
and Throwable
are checked exceptions. The rules for checked exceptions say that they must either be caught within the method (or lambda) in which they are thrown, or they must be declared in the throws
list of the method (or functional interface).
(See also: What does "error: unreported exception <XXX>; must be caught or declared to be thrown" mean and how do I fix it? for some background.)
Neither of those things is practical in your example. So you should avoid throwing checked exceptions in that context. Use unchecked exceptions instead; i.e. RuntimeException
or subclasses.
Note that it is a bad idea to declare a method as throws Throwable
or throws Exception
. This effectively forces the caller to deal with1 exceptions that it (typically) has no knowledge of. If you want to use checked exceptions, use ones that are specific to the "exceptional condition" you are signalling. Declare a custom exception if necessary.
1 - ... either by handling them, or declaring them in its method signature!
Upvotes: 1