2011-01-27 67 views
14

這是關於我的回答在這個線程提供了一個問題:Are Inner Classes lightweight?重新匿名內部類的多個實例

我從我的閱讀請記住,如果你只能從單一的匿名創建一個對象內部類,因此,如果你想說創建一個ActionListener類,並且想從這個類創建多個對象(不使用反射),不要使用匿名內部類,而是使用私有內部類或者站點一起上課,但人們告訴我我錯了。有人能爲我澄清這一點嗎?請檢查鏈接,因爲它包含更多詳細信息,但如果有任何不清楚的地方,請詢問!

+0

謝謝,我想我明白,但是這需要創建多個類 - 如果我理解正確。問題是給出一個匿名內部類的代碼,你可以創建它的多個對象實例嗎?而且我不是說使用循環,因爲再次,這將創建多個類--- oops,您的評論去哪兒了? – 2011-01-27 18:04:57

+1

我認爲你的意思是它的類的多個實例?一個對象本身就是一個實例 – 2011-01-27 18:05:57

+1

@Hovercraft,不能在註釋中放置可讀代碼。 ;) – 2011-01-27 18:06:47

回答

16

您可以創建任意數量的匿名類的對象,你可以在你的代碼的一個地方創建它們(除非你複製的代碼)

ExecutorService service = ... 
for(int i=0;i<1000*1000;i++) { 
    final int finalI = i; 
    service.submit(new Runnable() { 
     public void run() { 
     System.out.println("Task "+finalI+" run."); 
     } 
    }); 
} 

此代碼將創建同一類1個億個對象。

4

目前還不清楚。也許如果我們梳理規範,我們會發現內部類應該和普通類相同的證據。然而在本質上,類別取決於外部實例,該類別不存在於該實例之外。這與存在基本上永久存在的「正常」類不同。當然,兩個外部實例的兩個內部類彼此有些相關,由相同的源代碼創建,但這並不意味着它們必須相同或者相等。有證據表明,Java設計者是這樣想的,靈魂中的內部類生活在外部實例的範圍內。例如,好奇的語法outerInstance.new InnerClass()。例如,沒有靜態變量,沒有內部類的靜態初始化器。在討論類卸載[1]時,我們看到這個論證並不適用於內部類,可以想象內部類可以被卸載!可以想象,一個VM爲每個新的外部實例創建一個新的內部類。

實際情況並非如此,內部類的確被視爲與普通類相同。但從概念上講,我會一直將它們視爲實例私有類。

[1] http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

更新:根據[2]

兩個引用類型相同運行時類型,如果他們......具有相同的二進制名稱

和[3]

匿名類(第15.9.5節)的二進制名稱由它的立即封閉類型的二進制名稱,後跟$,後跟非空序列的數字。

所以一個匿名類有一個二進制的名字,所以只有一個運行時類型。規範保證我們匿名類的不同實例具有標識類。

[2] http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.4

[3] http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.html#44909