“lambdas do NOT create a new scope, they share the same scope as the enclosing block/ environment” is an almost correct statement (they do create a new scope, but not the way inner classes do), but doesn’t have anything to do with runtime performance. This has to do with correctness of the code.
Within an anonymous inner class, identifiers may get resolved through the lexical scope, finding a match in the surrounding scope, or by inheritance, finding a match in the class hierarchy of the anonymous inner class. The rules for resolving identifiers in this scenario are complex and easy to confuse.
Further, the body of an anonymous class creates a new scope that allows to create variables having the same name as local variables of the surrounding context, shadowing these variables.
In contrast, a lambda expression works like other expressions within the context they are written in. They do not inherit any members from the functional interface they will get converted to, they can not create new variables shadowing existing local variables and even this
and super
have the same meaning as within the surrounding context:
JLS§15.27.2. Lambda Body
Unlike code appearing in anonymous class declarations, the meaning of names and the this
and super
keywords appearing in a lambda body, along with the accessibility of referenced declarations, are the same as in the surrounding context (except that lambda parameters introduce new names).
So when you have the expressions x.foo(y)
and () -> x.foo(y)
within the same block, it will be obvious whether x
and y
will be the same x
and y
for both expressions and hence, it will be the same foo
method in each case, which you can not say that simple for anonymous inner classes, as you have to analyze the entire inner class and its type hierarchy first.
This makes lambda expressions ideal for scenarios where you want to define a local function and, e.g. pass it to a method as a parameter, without even thinking about the actual interface
being used. The interface itself does not influence the lambda expression beyond defining the functional signature.
But this also implies that there might be use cases of anonymous classes that can’t be covered by lambda expressions. But the purpose of lambda expressions isn’t to be a general replacement for anonymous inner classes.
When it comes to performance or easy of parallel processing, shmosel’s answer says it already. We can’t make such general statements without knowing which operation/problem we are looking at and which solutions we are actually comparing.