4

我读了 Effective Java,并写了

如果一个类不能成为不可变的,则尽可能限制它的可变性......

...使每个字段都成为最终的,除非有令人信服的理由使它成为非最终的。

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

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

但我的东西真的不是好主意..

请解释一下何时使类不可变。

4

3 回答 3

6

不,你不需要总是让你的 POJO 不可变。就像你说的,有时这可能是个坏主意。如果您的对象具有随时间变化的属性,那么 setter 是最舒适的方法。

但是你应该考虑让你的对象不可变。它将帮助您发现错误、更清晰地编程和处理并发。

但我认为您引用的内容说明了一切:

如果一个类不能成为不可变的,则尽可能限制它的可变性......

...使每个字段都成为最终的,除非有令人信服的理由使它成为非最终的。

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

于 2012-07-29T10:45:54.267 回答
1

1. APOJO是一个有private Instance VariableswithGetterSetter methods 的。

2.String class一直需要一个常量 behavior/implementation的类必须是 final的,而不是需要随时间变化的。

3.为了使一个类不可变,final 不仅是解决方案,One can have private Instance variables, with only Getter methods。并且他们的状态被设置为 Constructor.

4.现在根据您的编码决定,尝试纠正哪些字段需要在整个程序中保持不变,如果您觉得某些字段需要immutable,请将它们定为最终。

5. JVM使用一种称为常量折叠的机制来预先计算常量值。

于 2012-07-29T10:50:57.887 回答
1

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

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

于 2012-07-29T10:55:07.800 回答