2012-09-24 141 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图书可能会让你看到该部分的预览。

一本好书,详细讨论这样的话题。