不可变对象是指在创建后无法改变其状态的对象。它们的主要特性包括:
不可变对象的优点:
不可变类的实现示例:
public final class Person { private final String name; private final int age; private final List<String> phones; public Person(String name, int age, List<String> phones) { this.name = name; this.age = age; // 保护传入的列表不被修改 this.phones = Collections.unmodifiableList(new ArrayList<>(phones)); } public String getName() { return name; } public int getAge() { return age; } public List<String> getPhones() { return phones; } // 返回只读列表 }
为什么Java中的String是不可变的,如果不是这样会发生什么?很多人回答“为了安全”,但这在实践中意味着什么?
答案:
String被广泛使用:作为集合中的键,在安全逻辑中(例如,密码)。如果可以通过一个引用改变字符串,这将影响所有指向同一对象的其他引用,从而使集合的正确工作变得不可能(例如,在计算hashCode时的HashMap),并可能导致安全漏洞。
故事
Collections.unmodifiableList。故事
Date,List)。在一个线程中修改了配置,而在另一个线程中获取过时或不一致的数据,这导致业务算法错误触发。故事
在登录系统中,密码存储在可变对象中。由于不安全的访问,另一个用户的密码意外“泄露”,因为同一个对象实例被多个线程使用。