要保证对象不可变(Immutable),核心思想是:对象一旦创建,其状态(字段值)就不能被修改。下面从设计原则、语言特性、常见陷阱几个层面系统说明,并给出 Java / JavaScript / Python 的示例。
setterfinal class__slots__final / const / 私有 + 只读import java.util.Date;
public final class Person {
private final String name;
private final int age;
private final Date birthDate;
public Person(String name, int age, Date birthDate) {
this.name = name;
this.age = age;
// 防御性拷贝
this.birthDate = new Date(birthDate.getTime());
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Date getBirthDate() {
// 再次防御性拷贝
return new Date(birthDate.getTime());
}
}
| 检查项 | 是否满足 |
|---|---|
类为 final |
✅ |
字段为 private final |
✅ |
| 无 setter | ✅ |
| 可变对象字段被拷贝 | ✅ |
| 无暴露内部引用 | ✅ |
Object.freezeconst person = Object.freeze({
name: "Tom",
age: 18
});
// 无效(严格模式下报错)
person.age = 20;
⚠️ 注意:
Object.freeze 是浅冻结const obj = Object.freeze({
data: { x: 1 }
});
obj.data.x = 2; // ❌ 仍然可改
function deepFreeze(obj) {
Object.values(obj).forEach(v => {
if (typeof v === "object" && v !== null) deepFreeze(v);
});
return Object.freeze(obj);
}
namedtuple(最简单)from collections import namedtuple
Person = namedtuple("Person", ["name", "age"])
p = Person("Tom", 18)
# p.name = "Jerry" ❌ 报错
class Person:
__slots__ = ("_name", "_age")
def __init__(self, name, age):
object.__setattr__(self, "_name", name)
object.__setattr__(self, "_age", age)
@property
def name(self):
return self._name
@property
def age(self):
return self._age
def __setattr__(self, key, value):
raise AttributeError("immutable object")
public Date getBirthDate() {
return birthDate; // ❌
}
✅ 应返回拷贝
this.list = list; // ❌
✅ 应拷贝
✅ 线程安全
✅ 易于缓存
✅ 易于推理和调试
✅ 适合作为 Map / Set 的 key
❌ 对象非常大且频繁修改
❌ 性能敏感且对象生命周期短
不可变对象 = 不可继承 + 无修改方法 + 字段只读 + 对可变对象防御性拷贝
如果你有具体语言或场景(如 DTO、并发、函数式编程、Kotlin、C#),我可以针对性深入讲解。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。