Java中设计不可变对象需满足四点:1.所有字段private final;2.不提供修改状态的public方法,返回新对象;3.构造时对可变参数深拷贝或不可变包装;4.类声明为final以防继承破坏不可变性。
在Java中设计不可变对象,核心是确保对象一旦创建,其状态(即所有字段)在生命周期内无法被修改。这并非仅靠final修饰变量就能实现,而需从封装性、引用安全性和构造过程三方面协同保障。
这是不可变性的基础约束。任何可变字段都必须禁止外部直接访问和内部意外重赋值。
ArrayList、StringBuilder 等可变容器需额外防护包括 setter、add/remove 操作、clear、reverse 等会改变内部数据的方法。若需“更新”,应返回一个新对象。
String.replace() 返回新字符串,而非修改原字符串return new ArrayList(this.items); 而非 return this.items;
尤其当构造参数本身是可变对象时,若直接赋值,外部仍可通过原引用修改内部状态。
List、Date),应在构造器内进行深拷贝或不可变包装this.dates = Collections.unmodifiableList(new ArrayList(inputDates));
若允许继承,子类可能通过添加可变字段或重写方法破坏不可变契约。
final,杜绝继承带来的不确定性String、LocalDateTime、BigInteger 和所有基本类型的包装类。它们的设计已验证了上述原则的有效性。自定义不可变类时,可参考其源码中对参数校验、拷贝逻辑和防御性封装的处理方式。