2015-03-19 60 views
4

番石榴對象(不建議使用)或MoreObjects實現使用ToStringHelper類助洗劑圖案,所述add()函數是用於兩個基本類型和對象實現:番石榴,Objects/MoreObjects重載以避免自動裝箱。

public ToStringHelper add(String name, @Nullable Object value) 
public ToStringHelper add(String name, boolean value) 
public ToStringHelper add(String name, char value) 
... (other primitive type) 

類工作正常,即使沒有基本類型的過載,因爲自動裝箱會轉換並調用add(String,Object)函數。

所以我的問題是爲所有原語使用重載以避免自動裝箱的原因?

1.重複自動裝箱可能是一個巨大的開銷,但對於大多數情況下,這不會發生。有效的Java項目49,更喜歡原始類型對裝箱的基元。

2.Efffective的Java,項目41,P193,

一個安全保守的政策絕不是兩個超載出口相同數量的參數。

ToStringHelper示例明顯違反了此策略。作者繼續在類ObjectOutputStream中討論,不同的基元有它們自己的函數:writeBoolean(boolean),writeInt(int)...我從來沒有能夠理解使用不同名稱的優點來避免這個特定例子的重載,爲什麼它好?

任何意見將受到歡迎。

+0

我認爲在這裏違反#2的原因是沒有「破損」的情況 - 所有的原始類型的情況下做相同的東西,相應的盒裝類型會 - - 它不像它的罰款布爾,但你會得到'char'的異常。對於'String.valueOf'中的所有基本類型都有原始方法重載,它們能夠在不創建盒裝對象的情況下進行轉換,因此避免不必要的對象創建是有意義的(EJ Item 5)。 – 2015-03-19 05:23:31

+0

緊隨「安全保守政策」之上的是不太保守的聲明,「避免**令人困惑**超載的使用」。然後它會說'確切地說,構成混淆使用超載的因素有一些爭議'。我不認爲這是令人困惑的 - ToStringHelper的實現像你期望的那樣工作,對於你傳遞的所有內容。 – 2015-03-19 05:27:38

回答

2

我希望能給出這個答案,因爲它是對番石榴語言設計師的第二次猜測。他們也許能夠給你一個明確的答案,但是這是我猜測:

不久之前有效的Java第二版,第193頁的「保守策略」是語句:

避免混淆超載

的雖然它再繼續使用說

究竟是什麼構成了一個令人困惑的使用的超載是有爭議的

我認爲這不是一個混淆的重載使用。我要求這個,因爲類的邏輯行爲是相同的,如果它是爲實現簡單:

public ToStringHelper add(String name, @Nullable Object value) 
// No primitive overloads. 

不過,也有在其他EJ其中的建議來發揮作用。一個是第20頁的第49項,另一個是第5項「避免創建不必要的對象」。

沒有必要創建盒裝原語,因爲有String.valueOf(...)的重載處理每個基本類型,不可避免地比裝箱和調用toString()更有效。

請記住,番石榴是爲Google寫的,然後他們開源。按照Google的工作規模,使用原始類型和創建盒裝類型之間的區別,調用toString()並銷燬對象將會是可測量的。

添加這些重載將給予勝利,而主叫方無需做任何事情即可獲得。另一方面,如果存在不同名稱的重載(例如addChar,addBoolean),您實際上必須有意識地選擇您要調用的哪一個,並且很可能很多調用會懶惰地選擇Object重載,因爲嘿,它可以工作。保持相同的名稱可以使其透明工作。


番石榴有很多其他的例子可以避免不必要地通過重載創建對象。例如,ImmutableListof靜態工廠方法,重載爲零,一,二,...,十一個元素,然後其他一切都由可變重載處理。

可以實現簡稱爲ImmutableList.of(T... elements),但這需要每次一個可變數組,必須防守,以保證該列表的不變性內部複製的隱含創建。

因此,這些重載提供了更高效地構建列表的機會。作爲班級的用戶,您可能永遠不會注意到這一點。

+0

add()函數在很大的範圍內使用是一個很好的例子,ImmutableList的例子是正確的,我必須檢查出來 – 2015-03-19 12:20:20

2

我對對象進行了更改以添加額外的重載。 是的,這是爲了避免自動裝箱。我們偶爾會發現性能敏感的代碼和自動裝箱問題(我們經常會遇到另一個關於w.r.t. autoboxing的先決條件,但我們還沒有在那裏進行修改)。

FWIW,這裏是original bug report