需要我让所有类都不可变吗?

时间:2012-07-29 10:39:25

标签: java immutability effective-java

我读过Effective Java,并写了

  

如果一个类不能成为不可变的,那么就要限制它的可变性   可能...

  

......除非有令人信服的理由,否则每个领域都是最终的   非最终

所以我需要总是让我所有的POJO(例如简单的Book类,IDTitleAuthor字段)类不可变吗?当我想改变我的对象的状态时(例如用户在代表很多书的表中更改它),而不是setter使用这样的方法:

public Book changeAuthor(String author) {
   return new Book(this.id, this.title, author);  //Book constructor is private
}

但我真的不是个好主意..

请解释我何时使课程不可变。

3 个答案:

答案 0 :(得分:6)

不,你不需要总是让你的POJO不可变。就像你说的,有时它可能是一个坏主意。如果您的对象具有随时间变化的属性,则设置器是最舒适的方式。

但你应该考虑使你的对象不可变。它将帮助您找到错误,更清晰地编程并处理并发。

但我认为你引用了所有内容:

  

如果一个类不能成为不可变的,那么就要限制它的可变性   可能...

  

......除非有令人信服的理由,否则每个领域都是最终的   它是非最终的。

那是你应该做的。除非它不可能,因为你有一个二传手。但是要注意并发性。

答案 1 :(得分:1)

1。 POJOprivate Instance Variables GetterSetter 方法。

2。类似String class的类,需要始终需要常量 behavior/implementation       最终,而不是需要随时间变化的那个。

3。为了使类不可变,最终不仅仅是解决方案,一个人可以private Instance variables,只有Getter methods。并且他们的状态被设置为 Constructor

4。现在,根据您的编码决定,如果您认为某些字段是{{},请尝试纠正哪个字段需要在整个程序中保持不变 1}},让他们最终。

<强> 5。 JVM 使用一种名为常量折叠的机制来预先计算常量值。

答案 2 :(得分:1)

在OOP世界中,我们有。说明它是您对象中的所有属性。当您更改对象保证的状态时,返回新对象,您的应用程序将在并发环境中正常工作,而无需特定的事物(同步,锁定,原子等)。但是你总是创建新对象。

想象一下,您的对象包含100个属性,或者是一些包含100个元素的集合。要遵循不变性的想法,您还需要复制此集合。它的内存开销很大,也许是由GC处理的。在大多数情况下,手动处理对象状态比使对象不可变更好。在一些困难的情况下,如果并发问题非常困难,最好还是复制。这取决于任务。没有银弹。