温馨提示×

温馨提示×

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

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

怎样实现Java不可变类

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

在 Java 中,**不可变类(Immutable Class)**指的是:对象一旦创建,其内部状态就不能被修改。典型的不可变类有 StringIntegerLocalDate 等。

下面从实现原则 → 标准写法 → 示例 → 注意事项 → 常见面试点系统讲解。


一、实现不可变类的 5 个原则

✅ 1. 类用 final 修饰(防止被继承)

public final class Person {
}

✅ 2. 所有字段用 private final 修饰

private final String name;
private final int age;
  • private:外部无法直接访问
  • final:赋值后不能再修改

✅ 3. 不提供 setter 方法

只提供 getter(或根本不提供,直接暴露只读字段)


✅ 4. 通过构造方法初始化所有字段

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

✅ 5. 如果字段是可变对象,必须防御性拷贝

这是最容易出错的地方


二、标准不可变类示例(基础版)

public final class Person {

    private final String name;
    private final int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

✅ 特点:

  • String 本身不可变
  • int 是基本类型
  • 没有 setter
  • 类不可继承

三、包含可变对象的不可变类(重点)

❌ 错误示例(会破坏不可变性)

class Address {
    public String city;
}

public final class Person {
    private final Address address;

    public Person(Address address) {
        this.address = address;
    }

    public Address getAddress() {
        return address; // 外部可修改 Address
    }
}

❌ 外部可以改 address:

Address a = new Address();
Person p = new Person(a);
a.city = "Beijing"; // 破坏了不可变性

✅ 正确写法(防御性拷贝)

class Address {
    private String city;

    public Address(String city) {
        this.city = city;
    }

    public String getCity() {
        return city;
    }
}

public final class Person {

    private final Address address;

    public Person(Address address) {
        this.address = new Address(address.getCity()); // 拷贝
    }

    public Address getAddress() {
        return new Address(address.getCity()); // 返回拷贝
    }
}

✅ 关键:

  • 构造时拷贝
  • 返回时拷贝

四、使用静态工厂方法(推荐)

public final class Person {

    private final String name;

    private Person(String name) {
        this.name = name;
    }

    public static Person of(String name) {
        return new Person(name);
    }
}

✅ 好处:

  • 封装构造过程
  • 未来可缓存对象(如 Integer.valueOf)

五、不可变类的优点

✅ 线程安全(无需 synchronized)
✅ 可缓存(如 String 常量池)
✅ 易于推理、调试
✅ 适合作为 Map 的 key(如 String)


六、不可变类的缺点与解决

❌ 频繁创建对象
✅ 解决:

  • JVM 有 GC 优化
  • 使用对象池(如 Integer 缓存)

七、面试高频考点总结

✅ 面试官常问:

  1. 什么是不可变类?
  2. String 为什么是不可变的?
  3. 如何保证包含可变对象的不可变性?
  4. 为什么要防御性拷贝?

✅ 答题速记版

不可变类需要:
1️⃣ final 类
2️⃣ final 字段
3️⃣ 无 setter
4️⃣ 构造初始化
5️⃣ 对可变对象进行防御性拷贝


如果你愿意,我可以:

  • 用 **JDK 源码(如 String / Integer)**讲解
  • 对比 Java 14+ record 写法
  • 出一道 不可变类设计题给你练习
向AI问一下细节

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

AI