非静态内部类(后面讨论的都是非静态的)能够获取到外部包裹类的私有的字段/方法因为: 1.外部包裹类为了让内部类访问,会为每个字段创建一个包访问级别的方法; 2.内部类会产生一个外部包裹类的引用字段,并为访问外部包裹类的字段/方法产生一个静态方法,然后通过持有的外部包裹类的引用分别获取字段和调用相应方法。 例如:
public class OuterClass {
private int id;
public OuterClass() {
}
private void doSomeStuff() {
InnerClass innerObject = new InnerClass();
innerObject.doSomeOtherStuff();
}
private class InnerClass {
private InnerClass() {
}
private void doSomeOtherStuff() {
OuterClass.this.doSomeStuff();
}
}
}
产生的字节码为:
class OuterClass {
private int id;
private void doSomeStuff() {
OuterClass$InnerClass innerObject = new OuterClass$InnerClass();
innerObject.doSomeStuff();
}
int access$0() {
return id;
}
}
class InnerClass {
OuterClass this$0;
void doSomeOtherStuff() {
InnerClass.access$100(this$0);
}
static void access$100(OuterClass outerClass) {
outerClass.doSomeStuff();
}
static int access$0(OuterClass outerClass) {
return outerClass.id;
}
}
这将导致访问速度较慢,将外部包裹类中需要在内部类中访问的字段和方法声明为包访问权限的,将不会为了内部类访问编译时生成相应的静态方法,进行有效优化。
public class OuterClass {
int id;
void doSomeStuff() {
InnerClass innerObject = new InnerClass();
innerObject.doSomeOtherStuff();
}
private class InnerClass {
private void doSomeOtherStuff() {
OuterClass.this.doSomeStuff();
}
}
}