0

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.

Naman
  • 27,789
  • 26
  • 218
  • 353
Dave The Dane
  • 650
  • 1
  • 7
  • 18
  • Does this answer your question? [Java 8 Lambda function that throws exception?](https://stackoverflow.com/questions/18198176/java-8-lambda-function-that-throws-exception) – Jeroen Steenbeeke Jul 02 '21 at 06:46
  • Also: what you're seeing is the difference between checked and unchecked exceptions. Subclasses of RuntimeException and Error are unchecked, so don't require to be caught or declared. – Jeroen Steenbeeke Jul 02 '21 at 06:47
  • Does this answer your question? [Java 8: How do I work with exception throwing methods in streams?](https://stackoverflow.com/questions/23548589/java-8-how-do-i-work-with-exception-throwing-methods-in-streams) – sanjeevRm Jul 02 '21 at 06:47
  • I'm actually surprised that `new Throwable(...);` even compiles. – MC Emperor Jul 03 '21 at 09:27
  • @MCEmperor Why? `Throwable` is a concrete (non-abstract) class. – Mark Rotteveel Jul 04 '21 at 10:51
  • @MarkRotteveel Yeah, I found out myself as well. I somehow expected it to be an interface, for it ends with `able` (e.g. `Comparable`, `Serializable`...). Apparently, this is not the case for `Throwable`, and I somehow never examined the `Throwable` class. – MC Emperor Jul 04 '21 at 11:36

1 Answers1

1

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!

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216