標籤:java 內部類
常規內部類和普通類最大的不同就是,它能訪問外部類的私人執行個體域。下面是一個例子:
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 stubOuter outer = new Outer(false);outer.useInnerMethod();// 內部類對象必須依賴外部類對象Outer outer1 = new Outer(true);Outer.Inner inner = outer1.new Inner(); // 等價於Inner inner = outer1.new Inner();inner.innerPrint();}}
運行TestOuter的結果為:
print flase
print ture
內部類為何能訪問訪問外部類的私人執行個體域呢?我們反編譯編譯Outer類得到的兩個類檔案來得到答案。
在命令列運行javap -private Outer,得到如下結果:
Warning: Binary file Outer contains innerclass.OuterCompiled from "Outer.java"public class innerclass.Outer { private boolean isPrint; public innerclass.Outer(boolean); public void useInnerMethod(); static boolean access$0(innerclass.Outer);}
在命令列運行 -private Outer$Inner,得到如下結果:
Warning: Binary file Outer$Inner contains innerclass.Outer$InnerCompiled 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);
內部類就是通過這個方法實現訪問外部類的私人執行個體域的。
Java內部類(一)常規內部類