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

时间:2016-07-10 12:12:05

标签: java inner-classes

我正在学习Java,我正在学习的教程说Java不允许从方法m2()直接访问变量k(以下示例中的局部变量m1())因为它们是在同一个方法中创建的m1(),我将在编译期间得到一个错误(除非k被声明为final)。他们所说的是在方法执行完成后调用和销毁方法期间创建的局部变量(k)的原因,但是在实例化对象时创建了对象(o),并且在方法执行后仍然可以不销毁它。所以教程说如果在执行方法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();
    }
}

2 个答案:

答案 0 :(得分:7)

首先,您的程序编译并正常工作,因为您使用的是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();
}

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

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

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

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

答案 1 :(得分:0)

你讲过变量内部方法的概念是正确的。如果使用Java 1.7或更低版​​本编译,则会抛出编译错误。我猜你使用的是java 1.8。有一个概念调用最终变量和有效的最终变量。在java 1.8中,如果方法变量值已分配但未再次更改,则它可以执行此代码而不会浪费编译时间 错误。