温馨提示×

温馨提示×

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

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

怎么理解java不可变性

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

在 Java 中,**“不可变性(Immutability)”**通常指:一个对象在创建之后,它的状态(内部数据)不能再被修改。一旦对象被构造出来,它就“永远不变”。

下面从几个层面来理解。


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

不可变对象:创建后,其字段值不能被改变,且通常:

  • 所有字段是 private final
  • 不提供 setter
  • 对象内部引用的其他对象也最好是不可变的
  • 类一般是 final 的(防止被子类破坏不可变性)

典型例子:String

String s = "abc";
s = s + "d";

这里并不是修改了原来的字符串,而是创建了一个新的 String 对象 "abcd",原来的 "abc" 没变。


二、如何写一个不可变类

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 getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

特点:

  • final class:不能被继承
  • final 字段:构造后不能改
  • 没有 setter
  • getter 只返回值(不返回可变引用)

三、容易误解的“不可变”

1. final ≠ 不可变

final List<String> list = new ArrayList<>();
list.add("a"); // 可以!

final 只保证引用不变,但对象内容可以变。


2. 引用类型字段要小心

public final class Person {
    private final Date birthDate;

    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }

    public Date getBirthDate() {
        return birthDate; // 危险
    }
}

调用者可以:

person.getBirthDate().setTime(0);

✅ 正确做法(防御性拷贝):

public Date getBirthDate() {
    return new Date(birthDate.getTime());
}

或使用不可变类型(如 LocalDateTime)。


四、为什么要用不可变对象

1. 线程安全

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

2. 更容易理解和维护

“创建后就不会变” → 逻辑更简单。

3. 适合做 Map 的 key

如 String、包装类:

Map<String, Object> map = new HashMap<>();

如果 key 可变,会导致找不到值。

4. 缓存友好

如 Integer.valueOf(127) 有缓存。


五、不可变性的代价

  • 频繁修改 → 产生大量对象(如字符串拼接)
    • 解决:StringBuilder
  • 写起来略繁琐

六、一句话总结

Java 的不可变性不是“不能改引用”,而是“对象创建后内部状态不可变”。

如果你愿意,我也可以:

  • 用图示讲不可变 vs 可变
  • 对比 String / StringBuilder
  • 结合并发场景讲不可变的价值
向AI问一下细节

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

AI
助
手