温馨提示×

温馨提示×

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

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

如何保证java对象不可变

发布时间:2026-09-11 07:30:12 来源:亿速云 阅读:86 作者:小樊 栏目:编程语言

在 Java 中,**不可变对象(Immutable Object)**是指对象一旦创建,其状态(字段值)就不能再被修改。保证 Java 对象不可变通常遵循以下原则和做法:


一、保证不可变的核心原则

1. 类用 final 修饰(防止继承破坏不可变性)

public final class ImmutableClass {
}
  • 防止子类重写方法,从而改变行为

2. 所有字段用 private final 修饰

private final int value;
private final String name;
  • private:外部无法直接访问
  • final:引用一旦赋值不能更改

3. 不提供 setter 方法

  • 不写 setXxx() 方法
  • 不提供任何修改内部状态的方法

4. 通过构造方法完成初始化

public ImmutableClass(int value, String name) {
    this.value = value;
    this.name = name;
}

5. 对可变对象成员进行防御性拷贝(关键点)

如果字段是可变对象(如 DateList数组):

❌ 错误示例

private final Date date;

public ImmutableClass(Date date) {
    this.date = date; // 外部仍可修改
}

✅ 正确示例(防御性拷贝)

private final Date date;

public ImmutableClass(Date date) {
    this.date = new Date(date.getTime());
}

返回时也要拷贝

public Date getDate() {
    return new Date(date.getTime());
}

6. 对集合类型使用不可变集合

private final List<String> list;

public ImmutableClass(List<String> list) {
    this.list = List.copyOf(list); // Java 9+
}

public List<String> getList() {
    return list; // 已经是不可变集合
}

7. 不暴露 this 引用(防止构造泄漏)

// 错误
public ImmutableClass() {
    someMethod(this);
}

二、完整示例

import java.util.Date;
import java.util.List;

public final class User {

    private final String name;
    private final int age;
    private final Date birthday;
    private final List<String> roles;

    public User(String name, int age, Date birthday, List<String> roles) {
        this.name = name;
        this.age = age;
        this.birthday = new Date(birthday.getTime());
        this.roles = List.copyOf(roles);
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Date getBirthday() {
        return new Date(birthday.getTime());
    }

    public List<String> getRoles() {
        return roles;
    }
}

三、使用工具简化不可变类

1. Java 16+ 记录类(Record)

public record Point(int x, int y) {}
  • 自动 final
  • 自动不可变
  • 自动 equals/hashCode/toString

2. Lombok

@Value
public class Config {
    String key;
    int timeout;
}
  • @Value = 不可变类

四、不可变对象的好处

  • 线程安全
  • 易于缓存
  • 可作为 Map 的 key
  • 避免副作用

如果你有具体场景(如 DTO、配置类、并发对象),我可以给你更针对性的建议。

向AI问一下细节

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

AI