2012-09-24 71 views
7

夥計們,爪哇 - 克隆屬性getter方法內

我會經過這裏
http://viralpatel.net/blogs/most-useful-java-best-practice-quotes-java-developers/

2日報價說,提到Java的最佳編碼實踐,

報價2:決不讓一個類公衆實例字段

我同意這是絕對正確的,但是我被卡在下面的作者的建議幾行下面這個報價。

他說,


private String[] weekdays = 
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() { 
    return weekdays; 
} 

但寫getter方法並不完全解決我們的問題。該數組仍然可以訪問。使其不可修改的最佳方式是返回數組的克隆而不是數組本身。因此,getter方法將改爲

public String[] getWeekdays() { 
    return weekdays.clone(); 
} 

我從來沒有自己使用clone() Java類的任何getter方法裏面。

我想知道(因爲它提到是的良好做法之一) - 爲什麼一個should use/shouldn't useclone()內getter方法?並在哪些場景?

它有資格成爲Java的良好編程習慣嗎?

感謝

+2

IMO - 對於不可變對象和原始數據類型,不需要clone。對於其他任何事情,如果我們真的希望我們的數據安全,我們必須返回克隆副本而不是原始數據。 –

+2

您可以返回'Arrays.asList(平日)',這將是不可變的。 – Jivings

+2

@饋贈不是真的。該列表不會接受新的元素,但set()方法有效。 –

回答

3
private String[] weekdays =  
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() 
{  
    return weekdays; 
} 

如果你不使用clone方法,這個類的用戶可以做很多的缺德事:

  1. 變化天的順序,
  2. 變化天的名稱,
  3. ...

但是,返回克隆不會影響類和它的數據。所以,其他類的用戶不會受到影響。

+0

但是我之前沒有在任何網站上看到過clone()方法的推薦。我沒有看到大多數程序員(甚至是一些java怪胎)在他們的例子中使用它。我懷疑,如果這是一個很好的編碼習慣呢? :O –

+0

@bomslang很多東西會降低你的要求。正如Azodious指出的,不克隆(證明任何其他數據副本)可能會導致您的課程出現意外問題,但您需要確定這是否是您想要的行爲。你可能沒有看到它的原因是因爲它對大多數人來說是更加打字的。如果你看看Swing API,你會看到很多類似的實踐,當返回Dimension時,類通常會創建一個新的Dimension對象,使用它的內部引用作爲新類的種子,克隆它。 – MadProgrammer

+2

是的。並且我親自使用過它與案例幾乎相似的案例。但不應該盲目使用它,因爲如果一個重物被克隆,它會導致內存問題。因此,只克隆用戶不應修改的數據。 – Azodious

2

clone() or System.arraycopy()get()如果你想保證整個對象圖(包含數組)是不可變的。這通常在暴露數組的API是public並且數組中的值存在約束或者多個線程訪問對象時完成。在這種情況下,不變性很重要。

比方說,你有一個GroceryStore對象,它有getItemsSortedByPrice()方法。您將項目放在數組中,以價格維護訂單,但如果您返回此數組,則客戶端代碼可能會修改它並破壞對象的(內部)不變量。

如果這是內部代碼(即)不是公共API的一部分,並且您知道您不會修改該陣列,那麼克隆/應對可能不是必需的,因爲它會損害性能而沒有真正的好處。

全部取決於上下文。

數組只是對象,適用於普通對象的所有(im)可變性規則/實踐也適用於數組。

+1

+1 for System.arrayCopy( ),儘管我會推薦更多可用的版本Arrays.copyOf()(這當然在內部使用System.arrayCopy()) –

1

我認爲你的用例與建議的Java代碼不匹配。這個例子的用例不同於你的用例。

最後一個數組在我聽起來像Enums,我認爲這更符合您的要求。

5

這在本書「有效的Java」約書亞布洛赫討論。有一部分叫做「需要時製作防禦副本」(第二版第39節)。

我認爲Google圖書可能會讓你看到該部分的預覽。

一本好書,詳細討論這樣的話題。