11

I understand that a lambda in java cannot throw a checked exception, but can throw a RuntimeException, but why does the below code require brackets?

Map<String, Integer> m = new HashMap<>();
Integer integer = m.computeIfAbsent("", s -> {throw new IllegalArgumentException("fail");});

Why can't you have?

m.computeIfAbsent("", s -> throw new IllegalArgumentException("fail"));

Is it due to the assumption of the compiler that it would return in this instance an int, so therefor can't have a return of an exception, even though its thrown?

Holger
  • 285,553
  • 42
  • 434
  • 765
Ash
  • 2,562
  • 11
  • 31
  • 5
    basically, the `s->expr` form only works for expressions. `throw` is a statement. – ZhongYu Jan 31 '17 at 15:36
  • ah, this makes sense, if you put it in an answer I will put it as the marked answer – Ash Jan 31 '17 at 15:40
  • 2
    You may also read [this](http://stackoverflow.com/q/41482574/2711488) and [that](http://stackoverflow.com/q/24146285/2711488)… – Holger Feb 01 '17 at 10:42
  • @Holger cool, I did have a look for other questions, but I guess I was a bit more specific as to what I was looking at. – Ash Feb 01 '17 at 11:07

1 Answers1

12

The Java Language Specification describes the body of a lambda expression

A lambda body is either a single expression or a block (§14.2).

This, however,

throw new IllegalArgumentException("fail")

is the throw statement, not an expression. The compiler therefore rejects it as the lambda expression's body.

You can go down the rabbit hole and learn what all the types of expressions are, here (follow the grammar).

Ash
  • 2,562
  • 11
  • 31
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • +1. Confusingly enough, when you put an unbracketed `throw` statement into a lambda, `javac` gives the error `illegal start of expression` at the `throw`. – Jorn Vernee Mar 15 '17 at 16:13