3

I got a compilation failure

Compilation failure
[ERROR]  unreported exception java.lang.Throwable; must be caught or declared to be thrown

Why does this code not compile

Collections.singletonList(Arrays.asList("a", "b", "c")
    .stream()
    .findAny()
    .orElseThrow(() -> {
        String msg = "Failed";
        throw new IllegalArgumentException(msg);
    }));

while this seems okay

Collections.singletonList(Arrays.asList("a", "b", "c")
    .stream()
    .findAny()
    .orElseThrow(() -> new IllegalArgumentException("Failed")));

is this related to https://bugs.openjdk.java.net/browse/JDK-8056983 or is the first code block wrong?

In VS Code and in Eclipse I do not get a syntax error from the IDE.

M. Twarog
  • 2,418
  • 3
  • 21
  • 39
cuh
  • 3,723
  • 4
  • 30
  • 47
  • 8
    You need to do `return new IllegalArgumentException(msg)` in the first example, not `throw`. The `orElseThrow` function will do the throwing for you. – marstran Oct 10 '19 at 12:58
  • I cannot reproduce. Your first code snippet runs fine here (and doesn’t throw any exception). Tested on Oracle jdk-1.8.0_101 and jdk-11.0.3. – Ole V.V. Oct 10 '19 at 13:45
  • Both the above block of code compile fine for me. Is it an IDE specific issue, possibly? @marstran the `throw` within the block of code `{}` should compile as well. – Naman Oct 10 '19 at 13:46
  • @marstran your comment is misleading. Both lambdas are correct and `throw` is a valid statement in the first one. See my answer, please – Andrew Tobilko Oct 10 '19 at 14:35
  • @AndrewTobilko My comment is not misleading. I did not mention the compilation error at all. I simply pointed out that he should return the exception instead of throwing it himself inside `orElseThrow`. That's why I wrote a comment instead of an answer. – marstran Oct 10 '19 at 14:47

1 Answers1

2

The two code snippets are different. In the first one, you throw an exception in the lambda. In the second one, you return an exception from the lambda.

To make the two snippets consistent, change the first one to

Collections.singletonList(Arrays.asList("a", "b", "c")
    .stream()
    .findAny()
    .orElseThrow(() -> {
        String msg = "Failed";
        return new IllegalArgumentException(msg);
    }));
Dónal
  • 185,044
  • 174
  • 569
  • 824
  • the `throw` should compile as well, its the `{}` block and not an expression. Apart from the type of `Supplier` provided, there is not much difference in what is inferred by `orElseThrow` there. – Naman Oct 10 '19 at 13:49