2012-03-19 97 views
8

Java中的StringBuilderStringBuffer之間的差異已有詳細記錄,並且也是touched upon in StackOverflow爲什麼不讓StringBuilder和StringBuffer實現一個通用接口?

基本上,StringBuilderStringBuffer的非同步副本,它具有幾乎相同的接口,因爲它旨在作爲StringBuffer的更快捷的替代替代方案。他們的API實際上是相同的,他們實際上是在當前JDK中抽象類相同的不可訪問的的子類。

我想知道的一件事就是爲什麼他們不是公開相關。讓這兩個類實現一個通用接口,或者甚至將StringBuffer作爲StringBuilder的子類是合理的,從而允許兩個類都存在共享代碼。

那麼爲什麼這個強制分離呢?這是否讓程序員不會無意中將線程安全和線程不安全的代碼混合在一起?還是僅僅是一種設計監督,現在會被遺傳到永恆的盡頭?

編輯:

爲了把事情說清楚:我可以爲什麼事情都是這樣猜測,但我希望能具體引用到實際的決策,例如在JSR過程中。任何能夠說明對我而言是什麼的情況都會偶爾造成一定的困難。

編輯2:

兩個類都實現Appendable事實完全忘了。可能是因爲該特定界面在大多數情況下都沒有用處 - 它只能追加一個字符或一個準備好的對象,就是這樣。在大多數情況下,這兩個類都不是Object的子類。

編輯3:

嗯,這裏是正是這個問題從a semi-official source的理由:由圖書館團隊

評價:

它是由設計的StringBuffer和StringBuilder的沒有共同的 公共超類型。他們不打算成爲替代品:一個是 錯誤(StringBuffer),另一個(StringBuilder)是其替代品 。

很明顯,在某些情況下,缺少常見的超類型會減緩從StringBuffer到StringBuilder的希望遷移。另一方面 就是通過添加一個常見的超類型,我們會將過去的錯誤記錄下來,並將它們放入一個公共接口中,以便與我們聯繫所有的 時間。這不僅會減緩遷移速度,而且會導致遷移。

回答

3

我沒有JSR參考,但從我的exp。下面是幾個方面的原因:

  • StringBuffer子類的StringBuilder沒有因爲性能原因一個好主意。爲了使StringBuffer線程安全,您必須掩蓋每個致電StringBuilder的呼叫,這是很大的開銷。

  • 添加到上述點,可以進一步優化,如果你有超過一類的內部,這就是爲什麼Java的加入java.lang.concurrent超過java.util.Collections.synchronized*的API的原因直接訪問。隨着更多直接訪問提供更多優化選項。要詢問服務這一點Reference from the IBM blog

  • 進一步增加了第一點,我認爲這是一個設計監督作爲兩個類都final所以肯定他們不希望被繼承這些類。

  • 關於相同的接口,兩個類實現相同的接口,即Serializable, Appendable, CharSequence。所以他們是直接替換。唯一的問題是它們沒有實現一個通用接口,而是實現了三個通用接口。這是有道理的,因爲不需要有一個技術上會成爲當前接口總和的臃腫接口(Serializable, Appendable, CharSequence)。

編輯:

  • 爲了@MatthewFlaschen點,有蜜蜂它們是相同的B/W StringBufferStringBuilder但不是在任何實現的接口。這更多的是與向後兼容。你想添加一個新的API,但接口正在被許多其他類使用,所以改變一個接口可能是不可行的。這是Java人員可能做出的一個深思熟慮的決定。所以我不會說它是一個錯誤。

編輯2:

邊注:另外要注意的是,StringBuffer在1.0和1.5 StringBuilder介紹。所以在兩個類中都有,但不在接口中的apis稍後會介紹,而不是在創建這些類時。

+0

有一些方法,例如附加(長)在兩個類中,但沒有接口。 – 2012-03-19 03:45:37

+0

雖然我想像Vector和ArrayList擴展AbstractList,但StringBuffer和StringBuilder可以擴展一個類似的抽象類。我沒有看到最新的源代碼,但StringBuilder似乎是一個直接的StringBuffer減去同步。 – 2012-03-19 03:48:27

+0

@MatthewFlaschen append()來自Appendable。 – 2012-03-19 03:49:42

2

他們實際上都做了Appendable

我不認爲這是無用的。根據我的經驗,StringBuilder/StringBuffer用法的很大一部分只是處理字符串(實現CharSequence)。對於其餘的,您可以在通過之前調用String.valueOf

如果有另一個接口也有其他方法,如append(long),那將很方便。但這不是必需的。

具有通用接口是合理的。它們具有不同的性能和線程特性,但這對於JDK中的許多接口來說都很好並且真實。

例如,CopyOnWriteArrayList在基於陣列的線程安全列表(它使每寫一個新的列表),而LinkedList是一個非線程安全的鏈表。

+0

你沒有回答這個問題,或者甚至不明白爲什麼會這樣。 – FriendlyGuy 2012-03-19 03:17:07

+0

@MackieChan,我不同意。我說過「擁有共同的界面是合理的」,這是另一種說法:「是的,這是一種設計監督」。 – 2012-03-19 03:18:21

+0

老實說,Appendable滑倒了我的想法,主要是因爲我經常追加數字e.t.c.在我的代碼中。我沒有真正發現那個特殊的界面非常有用,因爲它強制你事先將所有的東西都轉換成字符串。更不用說現有的內容是不可改變的... – thkala 2012-03-19 03:29:55

相關問題