2012-06-25 53 views
8

Java的String存儲池的實現是否遵循flyweight模式?Java的String Intern是一個輕量級?

爲什麼我有這個疑問是,我看到實習生沒有涉及外在狀態。在GoF中,我讀到內部狀態和外部狀態之間應該有一個正確的平衡。但在實習生中,一切都是內在的。

或者應當說有相對於屬性沒有嚴格的規則和公正的分享對象以減少內存就足以稱之爲一個輕量級。

請幫我理解。不管實習的

回答

2

,Java的String利用通過共享char[]一個字符串,並經由substring從它衍生的那些和類似方法調用之間的輕量級圖案。但是,這有一個反面:如果你採取一個巨大的字符串的小字符串,巨大的char[]將不符合垃圾回收的條件。

注:作爲OpenJDK的版本1.7.0_06以上已經過時:代碼被改變,以使得char[]不再實例之間共享。 substring()創建一個新的數組。

+0

在flyweight對象中保持內在狀態並傳遞外在狀態信息 - 我們需要擔心這個嗎?因爲在GoF書中,我更看重內在/外在的分離。在char [] flyweight中,什麼是內在的和外在的? –

+0

這很簡單 - 'char []'完全是內在的,而對象表示的字符串完全是外在的。使用一個字符串,你甚至不知道'char []'存在。 –

+0

HotSpot實現最終將更改爲使用精確長度的char [](或可能爲'byte []'),而不使用偏移量和長度字段。真的有'char []'作爲一個單獨的分配也應該被淘汰。 –

4

是的String.intern()實現遵循flyweight模式。

由於javadoc

返回字符串對象的規範表示。最初爲空的 字符串由類String私人維護。

當調用實習方法時,如果池已包含等於(Object) 方法所確定的與此String對象相等的 字符串,則返回池中的字符串。否則,此 字符串對象將被添加到池中,並返回對此字符串 對象的引用。

因此,對於任意兩個字符串s和t,當且僅當s.equals(t)爲真時,s.intern()== t.intern() 才爲真。

所有文字字符串和字符串值的常量表達式是 實習。字符串文字在Java語言 規範的§3.10.5定義

的內部化字符串駐留在「彼爾姆根」的空間和通過.intern()返回您可以使用運營商總是==因爲.intern()返回字符串對象相同的對象相同的值。

然後記得.intern()方法不會產生泄漏,因爲今天的JVM能夠垃圾池。

嘗試閱讀這article太。

+0

但輕量級是關於共享對象內部。實習只是緩存整個對象。我在這裏看不到適合的地方。 –

+0

我的問題,「分享以節省內存本身是否有資格稱其爲輕量級?」不管外部/內在狀態的實現細節如何。 –

+0

也許我讀的是錯誤的,但是在維基百科,樣本返回並緩存整個對象([Flyweight pattern](http://en.wikipedia.org/wiki/Flyweight_pattern) ))。也許別人可以澄清這種模式。 – dash1e

-1

飛錘是分享對象immmutables內部。實習只是緩存整個對象。

+0

由於字符串是不可變的,我不明白你的意思 – Mishax

0

您已正確識別出Interning和Flyweight都基於相同的想法:緩存和共享通用狀態。在享有權重的情況下,在沒有內在狀態存儲的極端情況下,不需要該對象存在。只有指向外在狀態的指針依然存在,然後Flyweight已成爲Interning。

國際「真的」是或不是一種飛錘只是對定義的辯論。最重要的是理解一個人如何被視爲另一個人的專門實例,所以你很好。

0

正如其他人所說,String.intern()是關於緩存。它返回對池中已存儲的字符串文字的引用。通過這種方式,它與Flyweight模式相似,因爲它使用現有的對象,從而降低內存消耗並提高性能(儘管實習生在字符串池中也有自己的查找性能開銷)。因此,這兩者似乎相似,但實際上並非如此。