方法内部的类如何访问该方法的局部变量? [英] How a class inside a method access a local variable of that method?

查看:87
本文介绍了方法内部的类如何访问该方法的局部变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道所有局部变量都将存储在堆栈内存中,而对象和静态变量将存储在堆中.但是,当我遇到以下使我感到困惑的代码时.

I'm familiar that all local variables will be stored inside stack memory and objects and static variables will be stored in heap. But then when I came across the following code which confuses me.

public class Outer {

   private int a =10;

   public void outerMethod() {      
      int x = 30;

       class Inner {
          private int b = 20;
          public void innerMethod() {
            System.out.println("The Value of a is: "+a);
            System.out.println("The Value of b is: "+b);
            System.out.println("The Value of x is: "+x);
          }
       };

       Inner inner = new Inner();
       inner.innerMethod();
    }   
}

上面的代码运行正常.但是我的问题是 x 是externalMethod()的局部变量.当我们创建外部类的对象并对其调用外部方法()时, x 将存储在堆栈框架内,并且我还定义了内部类的类定义并创建了内部类的对象.它,然后我在上面调用innerMethod().
因此,内部类的对象必须存储在堆中.如果是这种情况,那么它将如何访问 x ??

The above code runs fine. But my question here is x is a local variable of outerMethod(). And when we create an object of Outer class, and invoke outerMethod() on it, x will be stored inside a stack frame, and I'm also defining a class definition of Inner class and creating object of it, then I'm invoking innerMethod() on it.
So that Inner Class's object must be stored inside heap. If that's the case then how could it access x??

推荐答案

Inner仅在x是最终的(或从Java 8

Inner can only access x if x is final (or, from Java 8 effectively final). Under the covers, the compiler will notice which outer variables are used by the Inner object and will pass them into the Inner constructor (these will be synthetic constructor parameters - generated by the compiler, so you will not see them). Then they will become final (again, synthetic = generated and hidden from you) fields of the Inner class. When you refer to x in the Inner class code, the compiler will substitute it with a reference to the synthetic x field in the Inner class where the value was copied.

您可以通过此有用的命令查看更多详细信息:

You can see more details with this useful command:

javac -d . -XD-printflat MyFile.java

将生成与实际字节码相对应的Java代码:

Will generate the Java code corresponding to the actual bytecode:

class Outer {

    /*synthetic*/ static int access$000(Outer x0) {
        return x0.a;
    }

    Outer() {
        super();
    }
    private int a = 10;

    public void outerMethod() {
        int x = 30;
        /*synthetic*/ {
        }
        ;
        Outer$1Inner inner = new Outer$1Inner(this, x);
        inner.innerMethod();
    }
}

class Outer$1Inner {
    /*synthetic*/ final Outer this$0;
    /*synthetic*/ final int val$x;

    Outer$1Inner(final Outer this$0, /*synthetic*/ final int val$x) {
        // Notice the synthetic references to the surrounding Outer object
        // and to the x local variable
        // Both become fields of Inner

        this.this$0 = this$0;
        this.val$x = val$x;
        super();
    }
    private int b = 20;

    public void innerMethod() {
        System.out.println("The Value of a is: " + Outer.access$000(this$0));
        System.out.println("The Value of b is: " + b);
        System.out.println("The Value of x is: " + val$x);
    }
}

您还可以注意到如何访问Outer.a-由于Inner被编译为普通的Java类",因此必须遵守可见性修饰符,因此JVM不允许直接访问私有字段Outer.a.但是,在编译期间,编译器会注意到您要从Inner访问此字段,并且由于它是内部类,因此将生成访问器方法Outer.access$000().由于Inner引用了Outer对象,因此它可以调用Outer.access$000(referenceToOuter)并获取Outer.a的值.

You can also notice how Outer.a is accessed - since Inner is compiled to a "plain old Java class" it has to respect the visibility modifiers, so the JVM would not allow for direct access to the private field Outer.a. However, during compilation, the compiler will notice that you want to access this field from Inner, and since it's an inner class, will generate an accessor method Outer.access$000(). Since Inner has a reference to the Outer object, it can call Outer.access$000(referenceToOuter) and get the value of Outer.a.

这篇关于方法内部的类如何访问该方法的局部变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆