生成了java中外部类的私有字段的访问器

时间:2014-07-30 12:33:31

标签: java inner-classes accessor

所以我对javac(版本1.7.0_65)生成的访问器有一个问题,允许内部类访问外部类的私有字段。

首先,这是一个简短的代码片段:

public class A {
    private int f = 0;

    class AA {
        public int m() {
            return f;
        }
    }
}

编译器在类A中生成一个访问器方法,以便方法m能够读取并返回f的值。

此访问器如下所示:

static int access$0(A);
    flags: ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: getfield      #12                 // Field f:I
         4: ireturn       

我的问题是:为什么这个访问器是作为静态方法生成的?是否存在非静态方法不起作用的情况?

2 个答案:

答案 0 :(得分:0)

这是因为在程序加载运行之前,必须在内存中支持代码的任何方法(这样就不会发生编译错误)。我们知道,静态方法在非静态成员(变量和方法)之前加载到内存中。此外,JVM线程调用该访问器方法。 JVM线程可以访问静态方法。

答案 1 :(得分:0)

IMO(至少)有两个理由做出这个决定:

首先:如果方法不是静态的,那么子类可能会覆盖它!

由于编译器无法确定运行时的类与编译时看到的类相同,因此无法生成一致的不相交命名。

考虑这个例子:

public class A {

    private int x = 1;

    private class AA {
        public int f() {
            return x; // would call access$0 on the outer instance
        }
    }
    public int getX() {
        return new AA().f();
    }
}
public class B extends A {

    private int y = 2;

    private class BB {
        public int g() {
            return y;
        }
    }
}

如果方法不是静态的,则以下代码将导致2而不是1:

assertEquals(new B().getX(), 2);

第二:访问器方法也必须可用于静态内部类。