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

如何防止多个Java对象指向同一引用?

解决Java对象引用赋值的问题

要彻底避免直接赋值共享引用导致的原对象被意外修改,核心思路是从类的设计层面入手,下面是两种可行方案:

方案一:将ComplexNumber改为不可变类

不可变类的对象一旦创建就无法被修改,即使直接赋值引用,也不用担心原对象被篡改。具体实现如下:

class ComplexNumber { // x + iy
    private final int x; // 用final修饰,确保初始化后不可修改
    private final int y;

    // 仅保留构造方法,移除所有setter方法
    ComplexNumber(int x, int y) {
        this.x = x;
        this.y = y;
    }

    ComplexNumber(ComplexNumber c) {
        this.x = c.x;
        this.y = c.y;
    }

    @Override
    public String toString() {
        return String.format("%d + %di", x, y);
    }

    // 仅提供getter方法,暴露属性但不允许修改
    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    // 如果需要"修改"操作,返回新的对象而非修改原对象
    public ComplexNumber addX(int delta) {
        return new ComplexNumber(this.x + delta, this.y);
    }

    public ComplexNumber addY(int delta) {
        return new ComplexNumber(this.x, this.y + delta);
    }
}

public class Main {
    public static void main(String[] args) {
        ComplexNumber a = new ComplexNumber(1, 2);
        // 即使直接赋值引用,也无法修改原对象
        ComplexNumber c = a;
        // 要变更属性只能生成新对象,原对象不受影响
        ComplexNumber d = c.addX(4);
        System.out.println(a); // 输出1 + 2i,未被修改
        System.out.println(d); // 输出5 + 2i
    }
}

这种设计下,所有对对象的“修改”操作都会返回新的ComplexNumber实例,原对象始终保持不变,从根源上消除了引用共享带来的风险。

方案二:通过规范引导(无法彻底杜绝)

如果不想改成不可变类,只能通过代码规范减少风险,但无法从语法层面禁止c = a这种赋值:

  • 在类的注释中明确标注,禁止直接赋值引用,必须使用拷贝构造方法或拷贝方法创建新对象
  • 提供静态拷贝方法简化拷贝操作,比如:
    public static ComplexNumber copy(ComplexNumber c) {
        return new ComplexNumber(c);
    }
    
    让使用者可以通过ComplexNumber.copy(a)直观创建拷贝对象

但这种方式只能依赖开发者自觉,无法从语言层面阻止引用赋值。

为什么无法完全禁止c = a这种赋值?

Java中对象类型的变量本质就是引用,=赋值操作就是传递引用,这是语言本身的特性,无法从语法层面禁止。因此最可靠的方案还是将类设计为不可变类。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:47:46