温馨提示×

温馨提示×

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

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

Java不可变究竟指什么

发布时间:2026-07-16 09:54:56 来源:亿速云 阅读:89 作者:小樊 栏目:编程语言

在 Java 里说“不可变(Immutable)”,通常是指:

对象一旦被创建,它的状态(字段值)就不能再被修改。

下面从定义、特征、示例、实现方式、常见误解几个方面系统说明。


一、什么是“不可变对象”

不可变对象(Immutable Object)

  • 对象创建完成后
  • 所有字段的值都不再发生变化
  • 对外暴露的任何方法,都不会修改内部状态
  • 任何“修改”操作都会返回一个新对象

✅ 例如:StringIntegerLocalDate

String s = "abc";
s = s.concat("def"); // 返回的是一个新的 String

二、Java 中“不可变”到底指什么

1️⃣ 不是指“变量不能被重新赋值”

final String s = "abc";
s = "def"; // ❌ 编译错误
  • final 只是变量不可再指向别的对象
  • 但对象本身是不是不可变,是另一回事

✅ 不可变 ≠ final 变量


2️⃣ 核心是指对象内部状态不可变

class User {
    private int age;

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

    public void setAge(int age) {
        this.age = age; // 可变
    }
}

❌ 这是一个可变对象


三、不可变对象的典型特征

一个标准的不可变对象:

  1. 类本身是 final 的
    • 防止被子类修改行为
  2. 所有字段都是 final
    • 保证构造完成后不可修改
  3. 字段私有
    • 不对外暴露内部状态
  4. 不提供 setter
  5. 如果字段是可变对象,要防御性拷贝
  6. 对象不会向外泄露可变引用

四、标准不可变类示例

✅ 不可变 Point

public final class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() { return x; }
    public int getY() { return y; }
}

✅ 无 setter
✅ 字段 final
✅ 类 final


五、String 为什么是不可变的

public final class String {
    private final char value[];
}
  • Stringfinal
  • value[]final
  • 不提供修改数组的方法
  • 任何“修改”都返回新 String

✅ 所以 String 是不可变对象


六、引用不可变 vs 对象不可变(重点)

1️⃣ 引用不可变

final List<String> list = new ArrayList<>();
list.add("a"); // ✅ 合法
  • list 不能再指向别的对象
  • ArrayList 内容可变

❌ 这不是不可变对象


2️⃣ 对象不可变(真正不可变)

List<String> list = List.of("a", "b");
list.add("c"); // ❌ 运行时异常

List.of() 返回的是不可变集合


七、不可变对象的好处

✅ 1. 线程安全

  • 不需要加锁
  • 多线程共享无风险

✅ 2. 可缓存、可复用

Integer a = 100;
Integer b = 100;
a == b; // true(缓存)

✅ 3. 更容易推理和调试

  • 状态固定
  • 不容易出 bug

八、不可变 ≠ 完全不能变(误区)

❌ 误区

“不可变就是完全不能改”

✅ 正确理解:

  • 对象本身不能改
  • 但可以:
    • 创建新对象
    • 替换引用
BigDecimal a = new BigDecimal("10");
BigDecimal b = a.add(new BigDecimal("5"));

九、什么时候该用不可变对象

✅ 适合:

  • 值对象(DTO、配置、金额、时间)
  • 多线程共享对象
  • 缓存 key
  • 函数式风格代码

❌ 不适合:

  • 频繁修改的大对象(性能问题)

十、一句话总结

Java 的“不可变”指的是:对象一旦创建,其内部状态就永远不会改变,任何修改都会产生新对象。

如果你愿意,我也可以:

  • 对比 String vs StringBuilder
  • 讲不可变集合(List.ofMap.of
  • 讲不可变对象在并发中的优势
  • 结合 JVM 内存模型解释为什么安全
向AI问一下细节

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

AI