0
votes

From Java8 Lambdas vs Anonymous classes:
"...[Anonymous Inner Classes] introduce a new scope. That is, names are resolved from the AIC's superclasses and interfaces and can shadow names that occur in the lexcially enclosing environment. For lambdas, all names are resolved lexically."

Given the above statement regarding scope, what would a Java anonymous inner class that executed differently were it simply converted to a Lambda look like?

These two pieces of code look like they would behave identically:

    button.addClickHandler(clickEvent -> doSomething());

and

    button.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                doSomething();
            }
    });

but would that be the case if the inner method was instead doSomething(this)? or doSomething(myVariable)?

An example of a situation where the change in scope matters and how it would behave would be SUPER AWESOME to see. I understand that there are other ways that Lambdas are different than anonymous inner classes, but it is this change in scope that I haven't found any good explanations of.

2
You can't think of a scenario where code might behave (or compile) differently depending on what this points to? That shouldn't be too hard.shmosel
Specifically in reference to this: My question could read as "Is the scope difference between an AIC and a Lambda such that this is different between the two? If so, what does it point to in the case of a Lambda?"Glen Pierce
Yes, there's a difference. In an anonymous class it points to the anonymous class instance. In a lambda it points to whatever it would outside the lambda.shmosel
Note that there's a JEP under consideration that could lift restrictions on variable shadowing in lambdas in a future release.shmosel

2 Answers

4
votes

Consider the following example:

import java.util.function.Function;

public class Main {
    private static abstract class ParentClass implements Function<String, String> {
        protected String prefix = "parent_class_";
    }

    public static void main(String... args) {
        String prefix = "local_";
        printString("test", new ParentClass() {
            @Override
            public String apply(String s) {
                return prefix + s;
            }
        });
        printString("test", s -> prefix + s);
    }

    private static void printString(String baseString, Function<String, String> stringMapper) {
        System.out.println(stringMapper.apply(baseString));
    }
}

This prints

parent_class_test

local_test

In particular, prefix in AIC refers to a field in a parent class, while prefix in a lambda refers to a local variable.

0
votes

From: Lambda this reference in java
"When you use this inside an instance of an inner class you are referencing to the instance of the inner class. A lambda expression is not an inner class, this is not referencing to the instance of the lambda expression. It is referencing to the instance of the class you define the lambda expression in. In your case it would be a instance of Main. But since your are in a static method, there is no instance."

So, since a Lambda is not an inner class, but is instead a method, the scope of a Lambda function would be that of the enclosing class, not the Lambda (as would be the case for an anonymous inner class).