How do lambda expressions work in Java, and what are the parts of one?
A lambda is an implementation of a functional interface — an interface with exactly one abstract method. It has three parts: the parameter list, an optional arrow, and the body.
The parameter list may be empty, may name each parameter with a type, or may omit the types entirely — but it may not mix the two. The body is either a single expression or a block. An expression body is the value of the lambda; a block body needs an explicit return if the functional method returns a value.
The key mechanism is target typing. A lambda on its own has no type. It only becomes meaningful when it is assigned to a variable, passed as an argument, or returned from a method — and in each of those places the compiler knows the expected type. The compiler then checks that the lambda's parameters and body are compatible with the single abstract method of that interface. That is why (a, b) -> a + b compiles in one place and not another: the target type supplies the parameter types and the return type.
At run time a lambda is not an object you can cast to an interface the compiler does not know about in advance. The JVM creates an implementation of the functional interface, and the instance is created when the expression is evaluated. That is also why a lambda cannot reference this from the enclosing class in the way an anonymous class does — inside a lambda, this refers to the enclosing instance, not to a new anonymous object.