温馨提示×

温馨提示×

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

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

何时该用java不可变类

发布时间:2026-10-22 08:16:36 来源:亿速云 阅读:93 作者:小樊 栏目:编程语言

在 Java 中,不可变类(Immutable Class)是指对象一旦创建,其状态(字段值)就不能再被修改的类(如 String、Integer、LocalDateTime 等)。是否使用不可变类,取决于安全性、并发性、可维护性与业务语义。

下面从应该使用不可变类的场景、不适合的场景以及设计要点三个角度说明。


一、何时应该使用 Java 不可变类

1️⃣ 多线程 / 并发环境(最重要)

不可变对象天生线程安全,不需要加锁或同步。

✅ 适用场景:

  • 并发编程(线程池、异步任务)
  • 被多个线程共享的配置、参数对象
  • 缓存 key(如 Map 的 key)
final class Point {
    private final int x;
    private final int y;
    // 只有 getter,没有 setter
}

多个线程同时读,不会有并发问题。


2️⃣ 作为 Map / Set 的 Key

如果对象作为 HashMap 的 key,必须不可变,否则:

  • hash 值改变
  • 对象“丢失”
  • 出现诡异 bug
Map<UserId, User> map;

UserId 就应该是不可变类。


3️⃣ 值对象(Value Object / DTO 的只读版本)

当对象表示的是一个值,而不是一个可变实体时:

  • 金额 Money
  • 坐标 Point
  • 时间区间 DateRange
  • 配置项 Config
class Money {
    private final BigDecimal amount;
    private final Currency currency;
}

4️⃣ 防御性编程(防止外部修改)

返回内部对象时,防止被调用方修改:

public UserSnapshot getUser() {
    return new UserSnapshot(name, age);
}

而不是返回可变实体。


5️⃣ 函数式编程风格

  • 每次“修改”都返回新对象
  • 无副作用
LocalDate next = date.plusDays(1);

6️⃣ 缓存与序列化

  • 不可变对象可安全缓存
  • 序列化 / 反序列化不会破坏状态

二、何时不适合用不可变类

❌ 1. 状态频繁变化的大对象

例如:

  • 游戏角色
  • 订单状态机
  • 大型业务实体(Entity)

如果每次修改都创建新对象,会有:

  • 性能问题
  • GC 压力

❌ 2. 需要大量 setter 的业务对象

如 ORM 实体类(JPA Entity):

@Entity
class Order {
    private Status status;
    // 需要频繁变更
}

❌ 3. 性能极度敏感的场景

不可变 = 新建对象
在高频循环中需谨慎。


三、如何设计一个不可变类(Java 规范)

设计规则

  1. 类用 final(防止子类破坏不可变性)
  2. 所有字段 private final
  3. 不提供 setter
  4. 构造时完成初始化
  5. 对可变对象(如 List、Date)要防御性拷贝
public final class Student {
    private final String name;
    private final List<String> courses;

    public Student(String name, List<String> courses) {
        this.name = name;
        this.courses = List.copyOf(courses); // 防御拷贝
    }

    public List<String> getCourses() {
        return courses; // 已是不可变 List
    }
}

四、一句话总结

当对象表示的是“值”而不是“状态机”,或者需要在并发中被安全共享时,就用不可变类。

如果你愿意,我也可以:

  • 对比不可变类 vs 可变类示例
  • 讲 Java 17+ 的 record
  • 结合你当前项目场景给建议
向AI问一下细节

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

AI
助
手