Java - 在getter方法中克隆属性

时间:2012-09-24 06:00:59

标签: java coding-style clone getter-setter

民间,

我正在阅读这里提到的Java最佳编码实践 http://viralpatel.net/blogs/most-useful-java-best-practice-quotes-java-developers/

第二句话说,

  

引用2:永远不要创建类public的实例字段

我同意这是完全正确的,但是我仍然坚持按照作者的建议在这句话下面几行。

他说,


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

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

但是写getter方法并没有完全解决我们的问题。该阵列仍然可以访问。使其不可修改的最佳方法是返回数组的克隆而不是数组本身。因此,getter方法将更改为

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

我从未在Java类的任何getter方法中使用clone()

我很想知道( 因为它被认为是良好做法之一 ) - 为什么一个should use / shouldn't use {{1里面的getter方法?在哪些情况下?

它是否有资格成为Java的良好编码实践?

由于

4 个答案:

答案 0 :(得分:5)

Joshua Bloch “Effective Java”一书中对此进行了讨论。有一个名为“在需要时制作防御性副本”的部分(第2版第39节)。

我认为Google图书可能会让您看到该部分的预览。

一本关于此类主题的好书。

答案 1 :(得分:3)

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

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

如果你不使用clone方法,这个类的用户可以做很多不道德的事情:

  1. 更改天数,
  2. 更改天数,
  3. ...
  4. 但是,返回克隆不会影响类及其数据。因此,其他类的用户不会受到影响。

答案 2 :(得分:2)

如果你想保证整个对象图(包含数组)是不可变的,那么<{> 1 clone() or System.arraycopy() get()。这通常是在公开数组的API是 public 并且数组中的值存在约束或者多个线程访问对象时完成的。在这种情况下,不变性很重要。

假设您有GroceryStore个具有getItemsSortedByPrice()方法的对象。您将项目保存在按价格维护订单的数组中,但如果返回此数组,客户端代码可能会修改它并破坏对象的(内部)不变量。

如果这是内部代码(即)不是公共API的一部分,并且您知道不会修改数组,那么克隆/应对可能不是必需的,因为它会在没有实际好处的情况下损害性能。

一切都取决于具体情况。

数组只是对象,适用于普通对象的所有(im)可变性规则/实践也适用于数组。

答案 3 :(得分:1)

我认为您的用例与提议的Java代码不匹配。该示例适用于与您不同的用例。

最后一个数组听起来像Enums,我认为这更符合您的要求。