java-嵌套類,java-嵌套
java允許在一個類中定義另外一個類,這就叫類嵌套。類嵌套分為兩種,靜態稱為靜態嵌套類,非靜態稱為內部類。
使用嵌套類的原因:
嵌套類也屬於類的成員,因此也可使用類成員的可視範圍控制修飾詞,內部類能夠使用其所在類的其他類成員,而靜態嵌套類則不能使用其所在類的其他類成員。
靜態嵌套類
與靜態方法與靜態欄位類似,靜態嵌套類是與其所在類相關的。靜態嵌套類不能直接使用執行個體變數或者執行個體欄位,而只能通過一個對象引用,可將靜態嵌套類視為跟其他頂級類一樣,只不過是內嵌在其他類裡面,方便打包。
靜態嵌套類的使用方法與類中的其他類成員類似,一下示範如何建立靜態嵌套類對象:
//StaticNestedClass為OuterClass的一個嵌套類OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
內部類(非靜態嵌套類)
內部類是與其所在類的執行個體相關的 ,能夠直接使用執行個體對象的方法和欄位,內部類與執行個體相關,所以內部類不能定義靜態成員。
如果需要建立內部類對象,首先需要建立該內部類所在的類的對象,如下所示:
//1建立內部類所在類的對象OuterClass outerObject=new OuterClass();//2建立內部類對象
//注意與靜態嵌套類的構造器使用方法的差異OuterClass.InnerClass innerObject = outerObject.new InnerClass();
嵌套類的遮蔽
當我們聲明一個類型時,如果其名稱與當前代碼塊(如一個方法內部)所在的代碼塊(如類內部)內的另一個類型的聲明含有相同的名稱,這種現象就叫遮蔽。需要用到被遮蔽的類型時,我們不能直接引用其名稱,如下例所示:
public class ShadowTest { public int x = 0;//嵌套類 class FirstLevel {//以下聲明會遮蔽其所在類的名稱為x的欄位 public int x = 1;//以下方法的聲明會遮蔽其所在類的名稱為x的欄位 void methodInFirstLevel(int x) { System.out.println("x = " + x); System.out.println("this.x = " + this.x); System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);//注意this關鍵詞的使用方法 } } public static void main(String... args) { ShadowTest st = new ShadowTest(); ShadowTest.FirstLevel fl = st.new FirstLevel(); fl.methodInFirstLevel(23); }}
上述代碼輸出為:
x = 23
this.x = 1
ShadowTest.this.x = 0
序列化,教程中強烈建議不要序列化內部類,在此留下疑問。
除了非靜態嵌套類意外,還有兩種內部類,一種是局部類,還有一種是匿名類。
局部類
局部類可以在任何代碼塊(花括弧內)中定義,一般應用於方法之中。
局部類可以使用其所在頂級類的類成員,此外,局部類也可以使用局部變數,然而,其所使用的局部類必須有final關鍵詞修飾,即不可變變數。在java SE8中,局部類可以使用本質上不變的局部變數,即該局部變數即便沒有final關鍵詞修飾,但實際上從初始化以後,其值從未改變過。
從java8開始,局部類也可以使用其所在方法的參數。
與內部類相似,局部類不能定義靜態成員,在靜態方法中定義的局部類不能使用執行個體成員。
在代碼塊中不能定義介面,因為介面本質是靜態。局部類中也不能定義借口成員,不過局部類中可以定義常量變數(用final修飾,類型為基礎資料型別 (Elementary Data Type)或者字串,編譯時間進行初始化)。
匿名類
匿名類能是代碼更加簡潔,它不需要名稱,可以聲明,執行個體化一步完成。
匿名類的聲明是一個運算式,如同調用一個構造器,不同的是其後還跟上了一個定義類的代碼塊。
匿名類的定義的運算式包含如下幾個部分:
- new關鍵詞
- 一個該匿名類需要實現的借口或者是繼承的父類的名稱
- 一對圓括弧,包含參數,實現一個介面時,參數部分留空
- 匿名類主體,跟類的主體類似, 可以定義方法
匿名類對於可使用的類型與局部類相同:
- 可使用其所在類的類成員
- 可使用其所在代碼塊的帶final修飾詞的局部變數,或者初始化後不再賦值的局部變數(java8)
- 對於遮蔽的類型,不能直接用名稱引用
同樣匿名類不能聲明靜態成員或者介面,但是可以聲明常量變數,在匿名類的類主體中,可以聲明執行個體欄位,執行個體方法,執行個體初始化代碼塊和局部類。