概念
官方说明如下:
The following rules define a simple strategy for creating immutable s. Not all classes documented as \"immutable\" follow these rules. This does not necessarily mean the creators of these classes were sloppy — they may have good reason for believing that instances of their classes never change after construction. However, such strategies require sophisticated analysis and are not for beginners.
- Don\'t provide \"setter\" methods — methods that modify fields or s referred to by fields.
- Make all fields
finalandprivate.- Don\'t allow subclasses to override methods. The simplest way to do this is to declare the class as
final. A more sophisticated approach is to make the constructorprivateand construct instances in factory methods.- If the instance fields include references to mutable s, don\'t allow those s to be changed:
- Don\'t provide methods that modify the mutable s.
- Don\'t share references to the mutable s. Never store references to external, mutable s passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable s when necessary to avoid returning the originals in your methods.
Applying this strategy to
SynchronizedRGBresults in the following steps:
- There are two setter methods in this class. The first one,
set, arbitrarily transforms the , and has no place in an immutable version of the class. The second one,invert, can be adapted by having it create a new instead of modifying the existing one.- All fields are already
private; they are further qualified asfinal.- The class itself is declared
final.- Only one field refers to an , and that is itself immutable. Therefore, no safeguards against changing the state of \"contained\" mutable s are necessary.
不可变对象的特点:
- 不要提供 setter 方法 - 修改字段引用的字段或对象的方法;
- 所有字段被 final 和 private 修饰;
- 不允许子类重写方法。最简单的方法是将类声明为 final。更复杂的方法是 private 在工厂方法中构造构造函数和构造实例;
- 如果实例字段包含对可变对象的引用,则不允许更改这些对象:
- 不要提供修改可变对象的方法;
- 不要共享对可变对象的引用。永远不要存储对传递给构造函数的外部可变对象的引用; 如有必要,创建副本并存储对副本的引用。同样,必要时创建内部可变对象的副本,以避免在方法中返回原始对象;
- 线程安全性;
- 会产生大量的“垃圾”;
看这样一个类:
package com.example.test;
import java.util.List;
/**
* @author Dongguabai
* @date 2018/12/17 14:30
*/
public final class ImmutableTest {
private final String name;
private final String address;
private final List<String> hobbies;
public ImmutableTest(String name, String address, List<String> hobbies) {
this.name = name;
this.address = address;
this.hobbies = hobbies;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public List<String> getHobbies() {
return hobbies;
}
}
构造这样一个类产生的对象其实并不是不可变对象,因为对象持有的引用依然可以被修改。
String 类的不可变性
Java 中的 String 类就是一个典型的不可变类,也许会有人说 String 类不是有一个 replace() 方法嘛,那 String 还是可以更改啊,可以看看 String 的 replace() 方法:
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
...
return new String(buf, true);
}
}
return this;
}
可以看到最终还是 new 了一个 String。
参考资料:
https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
继续阅读与本文标签相同的文章
上一篇 :
主流商用大数据平台的五层架构分析
-
特斯拉为自动雨刮创造了一个新的神经网络“Deep Rain”
2026-05-19栏目: 教程
-
银联:强力提升国际影响力
2026-05-19栏目: 教程
-
500亿元打水漂,贾跃亭造车太难申请破产,及时止损不算怂
2026-05-19栏目: 教程
-
望闻问切,用好人工智能
2026-05-19栏目: 教程
-
数字时代如何保护个人信息
2026-05-19栏目: 教程
