主題:Java的內部類——你知道多少?

quguiliang 13年前發布 | 2K 次閱讀

我在寫這篇文章之前,我對Java內部類也不是很清楚,只知道簡單的應用。前幾天有個朋友問我怎么理解Java內部類,我當時就有點傻了,想了半天也沒有說出來,我想,如果讓大家來回答這個問題,大家該怎么回答呢?我估計,總有一些人回答不上來的,或者說回答的不夠完整。我特意查了查,自己又總結了總結,在這給大家分享一下。 在說之前,我先列出幾個問題:

    1.外部類(非主類)通過怎樣的方式訪問內部類?

    2.內部類能不能訪問主類私有的屬性,為什么?

    3.內部類能不能繼承別的類和接口?

    4.內部類能不能是static的?

    5.在主類的方法里面可不可以定義內部類?

    6.初始化主類的時候是不是也把內部類給初始化了?為什么?

    7.怎樣寫一個匿名的內部類?

  我目前想到的就這些,在我給大家陳述之前,希望大家好好想想,再往下看:

  第一個問題:外部類是怎樣引用內部類的?這個問題,我想,可能有的人就會這樣寫:

  這是內部類:InnerClass.

1 public class MainClass {
2     
3     public class InnerClass{
4         public String name = "name";

6         public String getName() {
7             return name;
8         }
9
10         public void setName(String name) {
11             this.name = name;
12         }
13     }
14 }  
以下是引用:



1 public class CheckClass {
2     public static void main(String[] args) {
3         InnerClass innerClass = new InnerClass();
4         System.out.println(innerClass.getName());
5     }
6 } 

 
如果這樣寫的話,會報編譯錯誤。那么為什么會報錯呢?因為在Java的設計中,如果想訪問一個類的內部類,你必須通過宿主類去取它,然后,再對它進行操作,Java就是想這樣把內部類給封閉起來的,好吧,正確的寫法,我給大家貼出來:

  以下是內部類的寫法:

  

1 public class MainClass {
2     public InnerClass getInnerClass() {
3         return new InnerClass();
4     }

6     public class InnerClass {
7         public String name = "name";

9         public String getName() {
10             return name;
11         }
12
13         public void setName(String name) {
14             this.name = name;
15         }
16     }
17 }

  如果你想訪問Java內部類,你必須先拿到它的宿主類,這樣你才能對內部類進行操作:



1 public class CheckClass {
2     public static void main(String[] args) {
3         MainClass mainClass = new MainClass();
4         System.out.println(mainClass.getInnerClass().getName());
5     }
6 }

  這樣的話,編譯就不會報錯了。







  好了,該回答第二個問題了,就是內部類能不能訪問宿主類的私有屬性?回答是可以的。如果,你會看JVM的源碼的話,你就會看到,在編譯內部類調用主類私有變量時,會把它們轉換成一種特殊的符號,JVM會把這種符號解析成公有的,然后讓內部類調用。代碼很簡單,我就不貼了。

  接著回答第三個和第四個問題:就是內部類能不能繼承別的類和接口?內部類能不能是static的?為什么不能,當然可以,這些并沒有什么約束。你自己可以試一下。

  該第五個問題了:在主類的方法里面可不可以定義內部類?其實,這個問題,在我回答第一個問題的時候,已經把答案告訴了大家,就是在getInnerClass()方法里面,不就是new了一個內部類嗎。

  第六個問題:初始化主類的時候是不是也把內部類給初始化了?為什么?這個嘛,如果反過來說就對了,因為如果,你想調用內部類,你就得初始化它的主類,因此,你在初始化內部類時就初始化了主類,但是,你初始化主類,如果不是顯示的去初始化,你就不可能初始化它的內部類,盡管內部類是在主類的里面。如果,你有時間,你可以到編譯的主類文件去看看。

  最后一個問題就是:怎樣寫一個匿名的內部類?如果大家搞過Java Swing或者Android開發,這個問題對你來說很簡單,因為在隨便的一些事件里,你就可以定義一個匿名的內部類,然后實現它的方法。不過,為了讓更多的人明白,我把代碼貼出來,以下是我的代碼:

  這是要實現的那個接口:

1 public interface SuperInterface {
2     public void print();
3 }

  以下是主類的代碼:

1 public class MainClass {
2     
3     public SuperInterface print(){
4         
5         return new SuperInterface(){

7             public void print() {
8                 System.out.println("Hello Anonymity Interface");
9             }};
10     }
11 }

  其實上面的一段代碼就是一個匿名內部類,為什么叫匿名內部類呢?因為,你沒有給那個內部類起名字,而是直接實現那個接口,所以叫匿名內部類。

  好吧,我看寫的也不少了,不過,可能我還會有疏漏的地方,希望大家能參與進來共同討論

 本文由用戶 quguiliang 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!