cnova cnova - 19 days ago 8
Java Question

which variable is being accessed, local or class level?

Consider the following code given in Lambda Expressions :

import java.util.function.Consumer;

public class LambdaScopeTest {

public int x = 0;

class FirstLevel {

public int x = 1;

void methodInFirstLevel(int x) {

// The following statement causes the compiler to generate
// the error "local variables referenced from a lambda expression
// must be final or effectively final" in statement A:
//
// x = 99;

Consumer<Integer> myConsumer = (y) ->
{
System.out.println("x = " + x); // Statement A
System.out.println("y = " + y);
System.out.println("this.x = " + this.x);
System.out.println("LambdaScopeTest.this.x = " +
LambdaScopeTest.this.x);
};

myConsumer.accept(x);

}
}

public static void main(String... args) {
LambdaScopeTest st = new LambdaScopeTest();
LambdaScopeTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}


In the JavaDocs it is written that :


suppose that you add the following assignment statement immediately
after the
methodInFirstLevel
definition statement:

void methodInFirstLevel(int x) {
x = 99;
// ... }


Because of this assignment statement, the variable
FirstLevel.x
is not effectively final anymore. As a result, the Java
compiler generates an error message similar to "local variables
referenced from a lambda expression must be final or effectively
final" where the lambda expression myConsumer tries to access the
FirstLevel.x
variable:

System.out.println("x = " + x);



I'm unable to understand that at
System.out.println("x = " + x)
(statement A) how FirstLevel.x will be accessed? Shouldn't it be the
x
passed in the method
methodInFirstLevel(int x)
?

Answer

This appears to be an error in the tutorial. I believe the paragraph ought to read:

Because of this assignment statement, the parameter x is not effectively final anymore. As a result, the Java compiler generates an error message similar to "local variables referenced from a lambda expression must be final or effectively final" where the lambda expression myConsumer tries to access the x parameter:

System.out.println("x = " + x);

I rest my argument on two observations: the quoted error message says “local variables”, which might include parameters, but not fields. The quoted print statement prints 23, which is the value of the parameter, not the value of the FirstLevel.x.