8

伙计们,

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

第二句说,

引用 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 use clone()内部吸气剂方法?在哪些情况下?

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

谢谢

4

4 回答 4

6

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

https://www.informit.com/articles/article.aspx?p=31551&seqNum=2

一本讨论此类主题的好书。

于 2012-09-24T06:54:13.273 回答
3
private String[] weekdays =      
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"};  

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

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

  1. 改变天数,
  2. 更改日期的名称,
  3. ...

但是,返回一个克隆不会影响类和它的数据。因此,班级的其他用户不会受到影响。

于 2012-09-24T06:08:37.550 回答
2

如果你想保证整个对象图(包含数组)是不可变的,你可以继续clone() or System.arraycopy()get()这通常在公开数组的 API 是公共的并且对数组中的值有限制或当对象被多个线程访问时完成。在这种情况下,不变性很重要。

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

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

一切都取决于上下文。

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

于 2012-09-24T06:27:09.390 回答
1

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

最终的数组对我来说听起来像Enums,我认为这更符合您的要求。

于 2012-09-24T06:48:23.347 回答