当前位置: 首页 > news >正文

不可变类字段修复建议

在设计类时,将字段设为不可变(immutable)可提升代码的健壮性和线程安全性。以下是修复可变字段为不可变的建议和步骤:


核心原则

  1. 无 Setter 方法:禁止提供修改字段的方法。

  2. 字段用 final 修饰:强制在构造时初始化。

  3. 防御性拷贝:对引用类型字段,构造/返回时进行深拷贝。

  4. 类本身不可变:避免子类破坏不可变性(如将类声明为 final)。


修复步骤与示例

1. 基础类型字段

直接添加 final,移除 setter 方法:

java

// 修复前(可变)
public class User {private int age; // 可变字段public void setAge(int age) { this.age = age; }
}// 修复后(不可变)
public final class User {private final int age; // final 字段public User(int age) { this.age = age; } // 构造时初始化public int getAge() { return age; } // 无 setter
}
2. 引用类型字段(如数组、集合)
  • 构造时深拷贝

  • Getter 返回不可修改视图/拷贝

java

// 修复前(可变)
public class Data {private List<String> items; // 可变集合public void setItems(List<String> items) { this.items = items; }
}// 修复后(不可变)
public final class Data {private final List<String> items;public Data(List<String> items) {this.items = new ArrayList<>(items); // 深拷贝传入集合}public List<String> getItems() {return Collections.unmodifiableList(items); // 返回只读视图// 或返回深拷贝:return new ArrayList<>(items);}
}
3. 自定义对象字段

确保引用的对象本身不可变:

java

public final class Address { // 被引用的类也需不可变private final String city;public Address(String city) { this.city = city; }public String getCity() { return city; }
}public final class User {private final Address address; // 引用不可变对象public User(Address address) {this.address = new Address(address.getCity()); // 深拷贝}public Address getAddress() {return new Address(address.getCity()); // 返回拷贝}
}
4. 避免外部修改(防御性编程)
  • 如果字段是数组:

    java

    public final class ImmutableArray {private final int[] array;public ImmutableArray(int[] array) {this.array = Arrays.copyOf(array, array.length); // 深拷贝}public int[] getArray() {return Arrays.copyOf(array, array.length); // 返回拷贝}
    }

关键检查点

  1. ✅ 所有字段用 final 声明。

  2. ✅ 无 setter 方法

  3. ✅ 引用类型在构造时深拷贝外部数据。

  4. ✅ Getter 返回只读视图或深拷贝

  5. ✅ 类本身为 final(防止子类覆盖方法破坏不可变性)。


不可变类的优势

  • 线程安全:无需同步,天然线程安全。

  • 易于维护:状态在构造后永不改变。

  • 安全共享:可自由缓存、重用对象(如 String)。


注意事项

  • 深拷贝可能影响性能,需权衡场景。

  • 对复杂嵌套对象,确保整个引用链不可变。

  • 使用不可变集合库(如 Guava ImmutableList)简化实现。

http://www.dtcms.com/a/306108.html

相关文章:

  • 21. mysql redo 日志(下)
  • 模型选择与调优:从交叉验证到网格搜索的实践
  • 亚马逊广告进阶指南:如何优化流量实现新品快速起量
  • sqli-labs:Less-7关卡详细解析
  • NAT技术与代理服务
  • Jenkinsfile 报错
  • Elasticsearch服务器开发(第2版) - 读书笔记 第二章 索引
  • Docker常用命令速查手册:容器运维七维指南
  • Jupyter Notebook 中显示图片、音频、视频的方法汇总
  • arkui 动画曲线
  • react19更新哪些东西
  • vue3【组件封装】信息管理 S-comMangeInfo (含多条件搜索、分页表格、自带增删改查、重置密码等)
  • Java面试宝典:MySQL InnoDB引擎底层解析
  • VS调试前端项目时老是弹出Chrome无法更新的提示
  • 防抖(debounce)和节流(throttle)实现及原理讲解
  • dify离线插件打包步骤
  • Apache Ignite 与 Spring Data 集成
  • Electron + Fabric 打包遇到error LNK2001
  • 【面试场景题】随机立减金额计算
  • JVM——内存布局、类加载机制及垃圾回收机制
  • Http401和403什么意思
  • 颐顿机电携手观远BI数据:以数据驱动决策,领跑先进制造智能化升级
  • 皮尔逊相关系数的理论基础、统计特性与应用局限
  • 操作系统:总结(part_1,part_2)
  • Python Pandas.get_dummies函数解析与实战教程
  • Python在自动化与运维领域的核心角色:工具化、平台化与智能化
  • 从零开始,在Windows环境部署vllm
  • Boost.Asio:探索异步I/O引擎核心
  • stm32的PID控制算法
  • 学习游戏制作记录(冻结敌人时间与黑洞技能)7.30