正在访问哪个变量,本地或班级?

时间:2016-11-21 09:27:05

标签: java lambda scope

考虑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);
    }
}

在JavaDocs中写道:

  

假设您立即添加以下赋值语句   在methodInFirstLevel定义声明之后:

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

由于此赋值语句,变量FirstLevel.x不再是有效的最终结果。结果,Java   编译器生成类似于&#34;局部变量的错误消息   从lambda表达式引用必须是最终的或有效的   最终&#34; lambda表达式myConsumer尝试访问的位置   FirstLevel.x变量:

     

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

我无法理解在System.out.println("x = " + x)(声明A)如何访问FirstLevel.x?不应该是方法x中传递的methodInFirstLevel(int x)吗?

3 个答案:

答案 0 :(得分:2)

这似乎是本教程中的错误。我认为该段应该是:

  

由于此赋值语句,参数x不是   有效地终结了。结果,Java编译器生成了一个   类似于“从lambda引用的局部变量的错误消息   表达必须是最终的或有效的最终“lambda   表达式myConsumer尝试访问x参数:

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

我将我的论点放在两个观察上:引用的错误消息表示“局部变量”,可能包括参数,但不包括字段。引用的print语句打印23,这是参数的值,而不是FirstLevel.x的值。

答案 1 :(得分:0)

始终:如果方法中有任何局部变量,那么Java将首先选择局部变量,然后类原因是局部变量的范围非常有限,类变量可以在类的所有方法中访问

答案 2 :(得分:0)

Java始终使用具有给定名称的最内层变量。

导致此层次结构(降序):

  • 方法局部变量
  • 类变量/字段
  • 父类变量/字段
  • 包装类变量/字段

除非您使用this.varClass.var明确限定。