Effective Java 第二十四章 優先考慮靜態成員類

       首先要知道什麼是嵌套類,嵌套類就是在另一個類中定義的類。作爲嵌套類,它有別於頂級類(平時我們最常用的類),它在這個類的外部可以說是用不到或者說沒用的,如果有用那麼就應該作爲單獨的頂級類了。

有四種嵌套類:靜態成員類,非靜態成員類,匿名類和局部類。 其中後三種爲內部類(inner class)。

1. 靜態成員類

最簡單的嵌套類,幾乎可以作爲一個普通的類來看待,就是聲明在了一個類中,並因此可以像其他內部方法一樣訪問宿主類的承運,包括私有的。

一般的用途是作爲其宿主類的公共幫助類來使用,比如Operation 枚舉應該是 Calculator 類的公共靜態成員類。Calculator 客戶端可以使用 Calculator.Operation.PLUS

 

2. 非靜態成員類

首先,沒有static修飾符。非靜態成員類由於是非靜態,所以每個實例都隱含地與其宿主的實例相關聯。一般非靜態成員類的創建時通過宿主類的實例方法中調用非靜態成員類的構造函數來實現的。

非靜態成員類的一個常見用法是定義一個 Adapter [Gamma95],它允許將外部類的實例視爲某個不相關類的實例。 例如, Map 接口的實現通常使用非靜態成員類來實現它們的集合視圖,這些視圖由 Map 的 keySet ,

entrySet 和 values 方法返回。

如下面的JDK中HashSet的部分截圖所示。

集合接口(如 Set 和 List )的實現通常使用非靜態成員類來實現它們的迭代器:

比如截圖中的迭代器通過使用nextNode這個非靜態成員類來實現。

       如果你聲明瞭一個不需要訪問宿主實例的成員類,總是把 static 修飾符放在它的聲明中,使它成爲一個靜態成員類,而不是非靜態的成員類。這個主要是爲了避免由於非靜態成員類的實例隱藏的外部引用(引用到它的宿主實例)而導致的內存泄漏問題(由於這個隱藏的引用存在,導致雖然外部類沒有使用了,但是GC判斷其依舊有指向其的引用而導致沒有回收)。

3.匿名類

       沒有具體名字,不是宿主類的成員,也不和其他類成員一起聲明,而是在使用時進行聲明和實例化。匿名類的實現可以和lambda表達式一起看,匿名類是創建消防法對象和處理對象的首選在lambda出現之前,比如r->{r=r+1} 在以前就是new interface(int r ){r + =1;r}

       局部類是四種嵌套類中使用最少的。 一個局部類可以在任何可以聲明局部變量的地方聲明,並遵守相同的作用域規則。 局部類與其他類型的嵌套類具有共同的屬性。 像成員類一樣,他們有名字,可以重複使用。 就像匿名類一樣,只有在非靜態上下文中定義它們時,它們纔會包含實例,並且它們不能包含靜態成員。 像匿名類一樣,應該保持簡短,以免損害可讀性。

總結:有四種不同的嵌套類,每個都有它的用途。 如果一個嵌套的類需要在一個方法之外可見,或者太長而不能很好地適應一個方法,使用一個成員類。 如果一個成員類的每個實例都需要一個對其宿主實例的引用,使其成爲非靜態的; 否則,使其靜態。 假設這個類屬於一個方法內部,如果你只需要從一個地方創建實例,並且存在一個預置類型來說明這個類的特徵,那麼把它作爲一個匿名類; 否則,把它變成局部類。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章