温馨提示×

温馨提示×

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

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

java不可变对象怎么设计

发布时间:2026-10-01 19:10:30 来源:亿速云 阅读:94 作者:小樊 栏目:编程语言

在 Java 中,不可变对象(Immutable Object)是指创建后状态不能被修改的对象。设计不可变对象有一套成熟且推荐的做法,下面系统地讲一下。


一、不可变对象的设计原则

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

public final class User {
}

防止子类重写行为破坏不可变性。


2. 所有字段用 private final 修饰

private final String name;
private final int age;
  • private:外部不能直接访问
  • final:引用或值不能重新赋值

3. 不提供 setter 方法

// 没有 setName / setAge

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

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

5. 必要时对可变对象做防御性拷贝

⚠️ 重点易错点

如果字段是可变对象(如 Date、List、数组):

public final class Order {
    private final List<String> items;

    public Order(List<String> items) {
        this.items = new ArrayList<>(items); // 防御性拷贝
    }

    public List<String> getItems() {
        return new ArrayList<>(items); // 返回拷贝
    }
}

否则外部仍可通过引用修改内部状态。


6. getter 不直接暴露可变对象

  • 返回基本类型 / 不可变对象(String、Integer 等)可以直接返回
  • 返回可变对象必须拷贝

二、完整示例

public final class Person {

    private final String name;
    private final int age;
    private final List<String> hobbies;

    public Person(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = new ArrayList<>(hobbies);
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public List<String> getHobbies() {
        return new ArrayList<>(hobbies);
    }
}

✅ 创建后无法修改
✅ 线程安全
✅ 可安全共享


三、不可变对象的优点

  • ✅ 线程安全(无需同步)
  • ✅ 易于调试和测试
  • ✅ 可用作 HashMap 的 key
  • ✅ 防止意外修改

四、常见不可变类(Java 自带)

  • String
  • 包装类:Integer、Long、BigDecimal
  • LocalDate / LocalDateTime
  • Optional

五、进阶:Builder 模式(字段多时)

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

    private User(Builder b) {
        this.name = b.name;
        this.age = b.age;
    }

    public static class Builder {
        private String name;
        private int age;

        public Builder name(String name) { this.name = name; return this; }
        public Builder age(int age) { this.age = age; return this; }

        public User build() {
            return new User(this);
        }
    }
}

使用:

User u = new User.Builder()
        .name("Tom")
        .age(18)
        .build();

六、什么时候不适合不可变?

  • 对象非常大、频繁修改(性能问题)
  • 状态变化是核心业务(如订单状态机)

如果你愿意,我也可以:

  • 帮你审查现有代码是否真正不可变
  • 对比 不可变 vs 值对象(Value Object)
  • 讲 Java 17 Record(天然不可变)

你更想了解哪一块?

向AI问一下细节

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

AI
助
手