在 Java 中,“不可变机制”(Immutability)通常指:一个对象在创建之后,其状态(字段值)不能被修改。一旦对象被构造完成,它就始终保持不变,直到被垃圾回收。
下面从概念、实现方式、原理和典型应用几个方面说明。
不可变对象满足以下条件:
private 和 finalthis)public final class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
特点:
final class:不能被继承final 字段:赋值后不能改String 本身也是不可变的不可变对象天然线程安全:
// 多线程共享,不会出问题
private static final Person p = new Person("Tom", 18);
HashMap、HashSet 依赖 hashCode():
Map<Person, String> map = new HashMap<>();
map.put(p, "A");
p.setName("Jack"); // 如果可变,map 就坏了
例如:
StringIntegerBigDecimal防止:
| 类 | 说明 |
|---|---|
String |
最经典的不可变类 |
Integer / Long |
包装类不可变 |
BigDecimal |
精确计算 |
LocalDate / LocalDateTime |
Java 8 时间 API |
Optional |
容器但不可变 |
String 的不可变机制(重点)String s = "abc";
s = s + "d";
并不是修改原字符串,而是:
StringString 不变原因:
char[] value 是 private finalpublic final class Demo {
private final List<String> list;
public Demo(List<String> list) {
this.list = list; // 危险!
}
public List<String> getList() {
return list; // 危险!
}
}
外部仍可:
demo.getList().add("hack");
✅ 正确做法:
this.list = new ArrayList<>(list);
return Collections.unmodifiableList(list);
常见误区:
final Person p = new Person("Tom", 18);
final 只保证:
不保证:
StringBuilder 优化Java 的不可变机制,是通过“类封闭 + final 字段 + 无修改方法 + 防御性拷贝”来保证对象创建后状态不可变,从而实现线程安全和数据安全的设计机制。
如果你愿意,我也可以:
String 常量池原理免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。