解惑內部類(結合程式碼,一解就懂)
阿新 • • 發佈:2019-01-29
內部類有兩種情況:
(1) 在類中定義一個類(私有內部類,靜態內部類)
(2) 在方法中定義一個類(區域性內部類,匿名內部類)
1、私有內部類 —— 在方法之間定義的內部類,非靜態
我們首先看看類中內部類的兩個特點:
(1) 在外部類的作用範圍內可以任意建立內部類物件,即使內部類是私有的(私有內部類)。即內部類對包圍它的外部類可見。
例如 (實際上,內部類是可以設定為public公開的,但一般我是當做成員變數設定為private)
再者,Outer$Inner類中有一個指向外部類Outer的引用this$0,那麼通過這個引用就可以方便的得到外部類物件中可見成員。但是Outer類中的private成員是如何訪問到的呢?這就要看看下面Outer.class檔案中的祕密了。
(2)、編譯程式碼2生成 Outer.class檔案,然後使用 ReflectUtil.reflect("Outer") 對外部類Outer進行反射 。 執行結果 發現一個隱含成分如下:
- //程式碼1:內部類對外部類可見
- class Outer{
- //建立私有內部類物件
- public Inner in=new Inner();
- //私有內部類
- privateclass Inner{
- ...
- }
- }
- //程式碼2:外部類對內部類可見
- //(內部類可以訪問外部類的所有成員變數和方法)
- class Outer{
- //外部類私有資料域
- privateint data=0;
- //內部類
- class Inner{
- void print(){
- //內部類訪問外部私有資料域
- System.out.println(data);
- }
- }
- }
- //反編譯程式碼
- class Outer$Inner
- {
- Outer$Inner(Outer,Outer$Inner); //包可見構造器
- private Outer$Inner(Outer); //私有構造器將設定this$0域
- final Outer this$0; //外部類例項域this$0
- }
- //反編譯程式碼
- class Outer
- {
- staticint access$0(Outer); //靜態方法,返回值是外部類私有域 data 的值
- }
- package hr.test;
- //程式碼3:靜態內部類對外部變數的引用
- publicclass Outer{
- privatestaticint i=0;
- //建立靜態內部類物件
- public Inner in=new Inner();
- //靜態內部類
- privatestaticclass Inner{
- publicvoid print(){
- System.out.println(i); //如果i不是靜態變數,這裡將無法通過編譯
- }
- }
- }
- //反編譯程式碼
- class Outer$Inner
- {
- private Outer$Inner();
- Outer$Inner(hr.test.Outer$Inner);
- }
- class Outter{
- publicvoid outMethod(){
- finalint beep=0;
- class Inner{
- //使用beep
- }
- Inner in=new Inner();
- }
- }