从我们声明内部类的方法本地内部类中访问局部变量

Sri*_*vas 6 java inner-classes

我正在学习Java,我正在学习的教程说Java不允许从方法m2()直接访问变量k(下面例子中的局部变量m1())因为它们是用相同的方法创建的m1()并且我将在编译期间得到一个错误(除非k被声明为final).他们说的原因是一个局部变量(k)的方法过程中创建被称为和销毁之后所述方法执行完成,但是当该对象被实例化,并且可以仍然方法执行之后不会破坏在创建对象(○).所以这本手册说,如果你调用方法M2()或对象方法被执行后的M2 O(我不知道它是如何可能的)变量k将被销毁,将不可用.所以教程声称Java不允许这样的声明.(如果我的理解错误,请随时纠正我)

但是当我编译这个程序工作正常.我错过了什么吗?从我的解释角度来看,我理解这有点复杂,如果我的问题很明确,那么请随时问我是否有些不清楚.

在此先感谢您的帮助.

class innerclass_ex8
{
    int x = 10;
    static int y = 20;

    public void m1()
    {
            int k = 30;
            final int z = 50;
            class inner {
                public void m2() 
                {
                    System.out.println(x);
                    System.out.println(y);
                    System.out.println(k);
                    System.out.println(z);
                }
            }
            inner o = new inner();
            o.m2();

    }
    public static void main(String[] args)
    {
        innerclass_ex8 g = new innerclass_ex8();
        g.m1();
    }
}
Run Code Online (Sandbox Code Playgroud)

See*_*ose 8

首先,您的程序编译并正常工作,因为您使用的是Java 8.如果使用Java 7或更低版​​本,它甚至不会编译.

原因正如你所引用的那样.但我会尝试解释一下.请考虑以下代码:

public void m1() {
    int k = 30;
    class inner {
        public void m2() {
            System.out.println(k);
        }
    }
    inner o = new inner();
    k = 42;     // <= Note the reassignment here.
    o.m2();
}
Run Code Online (Sandbox Code Playgroud)

该方法应该o.m2()打印什么?"30"或"42"?两种产出都可以合理地论证.在声明和定义方法时,变量k的值为30.在调用方法时,变量k的值为42.

为了防止这种歧义,编译器不允许赋值给在这样的内部类(本地和匿名)中使用的变量.所以一定是final.

在Java 8中,这有点放松了.Java 8引入了有效最终的概念.声明和初始化但未再次分配的变量被认为是最终的.并且编译器允许该代码而不声明变量final.

事实上,在尝试编译上述代码时,Java 8中也会出现编译器错误.