2013-01-31 105 views
7

必須知道,我們可以使用雙大括號初始化來初始化java中的一個集合。並做了一些搜索,發現它不建議使用它,因爲它的性能問題。雙大括號初始化 - 優點

private static final Set<String> VALID_CODES = new HashSet<String>() {{ 
    add("XZ13s"); 
    add("AB21/X"); 
    add("YYLEX"); 
    add("AR2D"); 
}}; 

只是想知道,是否有任何積極的方面或雙重優勢的初始化?

+0

不,只有積極的一面是少代碼..但不可讀所有其他誰不知道雙括號初始化。 – Phani

+2

儘管可以用Java編程的人可讀性更強,但在非靜態環境中,您將獲得對封閉「this」的引用。你也可以選擇固定的引用來調用mutators時使用的final字段。這對於大多數Java程序員來說並不明顯,並且可能導致模糊的內存問題。 //無論如何,你應該寫一些類似'private static final Set VALID_CODES = Collections.unmodifiableSet(new HashSet (Arrays。asList(「XZ13s」,「AB21/X」,「YYLEX」,「AR2D」)));'顯然。 –

回答

5

由於其性能問題,不建議使用它。

我沒有看到任何性能問題。每當你看到有人說我做了/沒有做出某些表現的事情時,你應該期待看到詳細的分析,比較這些備選方案解釋瞭如何滿足特定的需求性能,而另一些則沒有。如果你沒有看到所有這些,你可能會認爲作者只是在猜測。

編輯:雖然我會承認每個類需要少量的時間來加載,運行的性能是完全一樣的。我在這裏已經展示https://stackoverflow.com/a/14627268/57695

如果您認爲它更簡單,更清晰,我會使用雙重大括號表示法。

一個缺點是,您正在改變可能會混淆不需要的功能的集合的類型。例如等於。

注意:正如Lukas Eder指出的那樣,如果您在非靜態環境中執行此操作,則需要小心。匿名子類集合將隱式地引用外部實例,並且如果它的壽命比集合長,那麼這將是內存泄漏。 Have you ever thought of the possibility of a memory leak?

+1

問題[Java的效率「雙Brace初始化」?](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization)實際上討論了性能問題,它*是* 比較慢。 –

+2

@AlvinWong這個測試看起來相當糟糕 - 特別是,當我看到一個測試返回「0 ms」時,我的第一個猜測是代碼還沒有運行(在這種情況下這是完全合法的,因爲結果是從來沒有用過的)。另外,JVM沒有正確預熱......我不相信這些結果。 – assylias

+0

以上線程的最佳答案有一些評論質疑性能測量 –

2

沒有什麼特別的性能問題(除了通過類加載器加載類的成本 - 可以忽略不計)

以上創建一個匿名類,因此它包含了一個隱含的this參照周邊情況。這可能會導致序列化框架出現混亂。例如你連續創建了你創建的匿名類,並且你突然發現你也試圖序列化包含的實例。

我會強調,匿名類可以在不同的框架和語言中使用很多(斯卡拉 - 我在看着你)。我從來沒有聽說有人認爲Scala由於類加載而導致性能問題。初始啓動可能是分數慢,但是記住JVM啓動,JIT熱身,任何網絡接入等

你可能會認爲你的應用程序佔用空間比較大,因爲更多的類。我懷疑(再次)的影響是微不足道的(除非你構造了一個匿名類的整個應用程序!)

+0

究竟我們在哪裏有一個匿名類? –

+0

我回復@Peter關於類加載 - 它並不總是可以忽略不計。當然,成本是O(1),因爲它僅用於類初始化。 – bestsss

+0

除了序列化之外,以這種方式創建內存泄漏的可能性更爲嚴重...... –