2013-02-22 104 views
9

Java字符串是不可變的,並且使用相同的值實例化多個字符串將返回相同的對象指針。 (這是否有一個術語?「池化」似乎適合,但這已經指的是通過執行更少的實例化來實現緩存以節省時間。)Java是否優化不可變對象?

Java是否也將此項目(沒有術語的項目)與其他項目用戶定義的)不可變的類? Java甚至可以檢測到一個類是不可變的,或者這對於字符串類來說是獨一無二的?

+0

+1有趣的問題。我相信Java可以識別只有最終成員的類,並將它們視爲不可變的,但我沒有關於這些的精確信息。我會關注這個問題。謝謝 – gd1 2013-02-22 09:24:39

+2

它沒有,並考慮如果你反正改變了不可變對象,反射會發生什麼.. – harold 2013-02-22 09:25:01

+0

我明白了,我對此有點驚訝。謝謝 – gd1 2013-02-22 09:25:35

回答

7

Wrt。字符串,你正在尋找的詞是interning

Java不會爲您自己的不可變對象執行此操作。不過,它確實緩存了盒裝原語的版本。有關更多信息,請參見wrapper class caching上的這篇文章。

0

字符串實際內容僅適用於String類。我想JVM不會將這些規則應用於用戶定義的類。

1

您正在查找的術語是itering。 Java在編譯過程中「自動」優化字符串,併爲開發人員提供了在運行時執行的可能性。 (根據JVM版本的不同,有關優化什麼的細節)

至於它是否適用於不可變對象。我不認爲Java支持任何可以解決相同情況的機制。字符串類型不是這個規則的豁免。

原因是,您是否必須使用運營商new來創建實例。如果您使用new創建字符串實例,您將始終獲得兩個不同的對象。

插入僅適用於字符串類型。但是這個概念是免費的,你可以將這種方法添加到你的不可變類中,並編寫一個可以做同樣事情的壓縮方法。

2

正如其他人在這裏所說的用Strings這個過程被稱爲實習。

其值得一提的字符串具有相同的文字值是相同對象的行爲可能會或可能不會在Java 7中做到真正從7日起:

在JDK 7,實習字符串不再分配在Java堆的永久生成中,而是分配在Java堆的主要部分(稱爲年輕人和老年人)以及由應用程序創建的其他對象中。此更改將導致更多數據駐留在主Java堆中,永久生成中的數據更少,因此可能需要調整堆大小。由於這種變化,大多數應用程序在堆使用中只會看到相對較小的差異,但是加載很多類或大量使用String.intern()方法的較大應用程序將會看到更顯着的差異。

查看Java SE 7 RFE瞭解詳細信息。

關於你自己的不可變對象,Java並沒有對它做任何特別的事情 - 它不知道它們是不可變的。它可能可能內聯方法稍微超過否則,如果它可以檢測到它的價值/可能,但就編譯器和JVM而言,他們只是另一個對象。

+2

哇,downvoted?我可以採取downvote,但會很高興知道爲什麼 – 2013-02-22 10:24:51