You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

引用可变对象时如何实现Java不可变类?及Company类有效性验证

嗨,咱们一步步来解决你的两个Java不可变性问题吧——这些都是设计不可变类时很常见的场景,问得非常好!

问题1:当类引用可变对象时,如何使其成为不可变类?

要让包含可变对象引用的类成为真正的不可变类,核心是彻底切断外部对内部可变对象的修改路径,具体要做到以下几点:

  • 把类标记为final:防止子类继承后通过重写方法破坏原有的不可变性规则
  • 所有成员变量用final修饰:保证成员变量的引用不会被重新赋值,确保对象状态初始化后就不会被替换
  • 构造方法中做防御性拷贝:不要直接接收外部传入的可变对象引用,而是创建它的副本。这样外部修改原对象时,不会影响类内部的状态
  • getter方法返回可变对象的副本:不要直接返回内部的可变对象引用,而是返回拷贝后的对象。避免外部通过getter拿到引用后,直接修改内部的可变对象
  • 移除所有修改状态的方法:比如setter方法,确保没有任何公开方法能改变类的内部状态
问题2:当前Company类的实现是否能使其成为有效不可变类?

先回顾一下给出的可变Employee类代码:

public class Employee {
    private String empName;
    private int empId;
    public String getEmpName() { return empName; }
    public void setEmpName(String empName) { this.empName = empName; }
    public int getEmpId() { return empId; }
    public void setEmpId(int empId) { this.empId = empId; }
}

当前的Company类不能成为有效的不可变类,有两个关键漏洞:

  1. 构造方法未做防御性拷贝:当外部传入一个Employee对象后,外部仍然持有该对象的引用。如果外部调用setEmpName或setEmpId修改这个对象的属性,Company内部的employee引用指向的是同一个对象,这会直接导致Company的内部状态被意外改变。

  2. getter方法直接返回可变对象引用:调用getEmployee()会拿到Company内部的employee引用,外部代码可以通过这个引用直接修改Employee的属性,同样会破坏Company的不可变性。

修复后的Company类实现

要让Company成为真正的不可变类,我们需要补上这两个漏洞:

public final class Company {
    final String companyName;
    final Employee employee;

    // 构造方法中对传入的Employee做防御性拷贝
    public Company(String companyName, Employee employee) {
        this.companyName = companyName;
        // 创建一个新的Employee对象,复制原对象的属性
        this.employee = new Employee();
        this.employee.setEmpName(employee.getEmpName());
        this.employee.setEmpId(employee.getEmpId());
    }

    public String getCompanyName() { return companyName; }

    // getter返回Employee的拷贝,而不是原引用
    public Employee getEmployee() {
        Employee copy = new Employee();
        copy.setEmpName(employee.getEmpName());
        copy.setEmpId(employee.getEmpId());
        return copy;
    }
}

这样修改后,外部无论怎么操作传入的原Employee对象,或者通过getEmployee()拿到的对象,都不会影响Company内部持有的Employee状态,从而保证Company是一个有效的不可变类。


内容的提问来源于stack exchange,提问作者Sid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:33:07