温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

什么场景用不可变类

发布时间:2026-07-16 10:02:50 来源:亿速云 阅读:87 作者:小樊 栏目:编程语言

在 Java 中,不可变类(Immutable Class)对象一旦创建,其状态(字段值)就不能再被修改。典型代表是 StringIntegerLocalDate 等。

下面从适合使用不可变类的场景原因两个角度来说明。


一、适合使用不可变类的典型场景

1. 多线程并发场景(最常见、最重要)

不可变对象是天然线程安全的,不需要加锁。

✅ 场景:

  • 多线程共享配置对象
  • 缓存 key
  • 并发计算中的中间结果

✅ 好处:

  • 没有竞态条件
  • 不需要 synchronized
  • 程序更简单、更安全
// 多个线程同时读,不需要任何同步
public final class User {
    private final String name;
    private final int age;
}

2. 作为 Map / Set 的 key(尤其是 HashMap、HashSet)

不可变对象 hashCode 稳定,不会破坏集合结构。

✅ 场景:

  • 缓存 key
  • 数据唯一标识

❌ 可变对象做 key 的风险:

  • 修改对象 → hashCode 变化 → 找不到原来的值
Map<UserId, UserInfo> cache = new HashMap<>();

3. 配置类 / 常量对象

配置一旦加载,不应再被修改。

✅ 场景:

  • 系统配置
  • 应用参数
  • 规则定义
public final class AppConfig {
    private final String env;
    private final int port;
}

4. 值对象(Value Object)

只关心“值是什么”,不关心身份。

✅ 场景:

  • 金额(Money)
  • 坐标(Point)
  • 时间(LocalDate)
  • 状态值
Money price = new Money(100);

特点:

  • equals() 比较
  • 通常是不可变的

5. 函数式编程 / 流计算

无副作用,结果可预测。

✅ 场景:

  • Stream API
  • Lambda 表达式
  • 数据处理管道
list.stream()
    .map(x -> new Result(x))
    .collect(...)

6. 缓存 / 享元模式(Flyweight)

对象可安全共享,减少创建成本。

✅ 场景:

  • 字符串常量池
  • 枚举
  • 常量对象池
Integer a = 100;
Integer b = 100;
// a == b(缓存)

7. 防御性编程(防止外部修改)

返回内部数据给调用方时,防止被篡改。

✅ 场景:

  • 对外暴露 DTO
  • API 返回值
public User getUser() {
    return new User(name, age); // 而不是暴露可变对象
}

二、不适合使用不可变类的场景

场景 原因
频繁修改对象状态 每次修改都会创建新对象,性能差
大对象、状态复杂 拷贝成本高
需要标识变化过程 需要记录“变化历史”

✅ 这类场景更适合可变对象 + 明确生命周期管理


三、什么时候“优先”用不可变类?

默认优先使用不可变类,除非你有明确理由不用它。

这是《Effective Java》的核心建议之一。


四、如何设计一个不可变类(简要)

public final class User {
    private final String name;
    private final int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String name() { return name; }
    public int age() { return age; }
}

要点:

  • final class
  • 所有字段 private final
  • 不提供 setter
  • 不暴露可变引用

五、一句话总结

只要对象“创建后不应该再改变”,就优先考虑不可变类,尤其是并发、缓存、值对象、配置、key 等场景。

如果你愿意,我也可以帮你判断某个具体业务对象是否应该设计成不可变类

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI