1. 程式人生 > >內部類對宿主類private成員的訪問

內部類對宿主類private成員的訪問

public class Foo {
    private class Inner {
        void stuff() {
            Foo.this.doStuff(Foo.this.mValue);
        }
    }

    private int mValue;

    public void run() {
        Inner in = new Inner();
        mValue = 27;
        in.stuff();
    }

    private void doStuff(int value) {
        System.out
.println("Value is " + value); } }

What’s important here is that we define a private inner class (Foo$Inner) that directly accesses a private method and a private instance field in the outer class. This is legal, and the code prints “Value is 27” as expected.

The problem is that the VM considers direct access to Foo’s private members from FooI

nnertobeillegalbecauseFooandFooInner are different classes, even though the Java language allows an inner class to access an outer class’ private members. To bridge the gap, the compiler generates a couple of synthetic methods:

/*package*/ static int Foo.access$100(Foo foo) {
    return foo.mValue;
}
/*package*/
static void Foo.access$200(Foo foo, int value) { foo.doStuff(value); }

The inner class code calls these static methods whenever it needs to access the mValue field or invoke the doStuff() method in the outer class. What this means is that the code above really boils down to a case where you’re accessing member fields through accessor methods. Earlier we talked about how accessors are slower than direct field accesses, so this is an example of a certain language idiom resulting in an “invisible” performance hit.

If you’re using code like this in a performance hotspot, you can avoid the overhead by declaring fields and methods accessed by inner classes to have package access, rather than private access. Unfortunately this means the fields can be accessed directly by other classes in the same package, so you shouldn’t use this in public API.

也就是說在內部類(與內部類宣告的訪問許可權無關)中對宿主類的private成員的訪問時,會生成 static 的 access$xxx 方法來對宿主類的私有成員的訪問做橋接。從而會增加類的方法數以及呼叫的開銷。
解決辦法是,將內部類需要訪問的成員變數或方法的訪問許可權宣告>=package,也就是非private即可。