常规内部类和普通类最大的不同就是,它能访问外部类的私有实例域。下面是一个例子:
package innerclass; public class Outer { private boolean isPrint; public Outer(boolean isPrint) { this.isPrint = isPrint; } public void useInnerMethod() { Outer.Inner inner = this.new Inner(); // 等价于Inner inner = new Inner(); inner.innerPrint(); } public class Inner { public void innerPrint() { // 内部类可以访问外部类的私有实例域 if (Outer.this.isPrint) {//等价于if (isPrint) { System.out.println("print ture"); } else { System.out.println("print flase"); } } } }
package innerclass; public class TestOuter { public static void main(String[] args) { // TODO Auto-generated method stub Outer outer = new Outer(false); outer.useInnerMethod(); // 内部类对象必须依赖外部类对象 Outer outer1 = new Outer(true); Outer.Inner inner = outer1.new Inner(); // 等价于Inner inner = outer1.new Inner(); inner.innerPrint(); } }
print flase
print ture
内部类为何能访问访问外部类的私有实例域呢?我们反编译编译Outer类得到的两个类文件来得到答案。
在命令行运行javap -private Outer,得到如下结果:
Warning: Binary file Outer contains innerclass.Outer Compiled from "Outer.java" public class innerclass.Outer { private boolean isPrint; public innerclass.Outer(boolean); public void useInnerMethod(); static boolean access$0(innerclass.Outer); }
Warning: Binary file Outer$Inner contains innerclass.Outer$Inner Compiled from "Outer.java" public class innerclass.Outer$Inner { final innerclass.Outer this$0; public innerclass.Outer$Inner(innerclass.Outer); public void innerPrint(); }
通过阅读反编译的结果,我们知道,编译器在内部类中添加了一个外部类对象的引用:
final innerclass.Outer this$0;我们知道,即使有了一个对象的引用,也不能通过.(点)直接操作对象的私有实例域,那么内部类是如何做到的呢?我们看到编译器还在Outer类中添加了一个方法:
static boolean access$0(innerclass.Outer);内部类就是通过这个方法实现访问外部类的私有实例域的。
原文地址:http://blog.csdn.net/l294265421/article/details/46574009