作为参数传递时,使对象不可变

ecl*_*pse 5 java

当作为参数传递时,我可以使对象不可变,因此被调用的方法不能改变它,但被调用者可以吗?

所以我有这样的事情:

Class Car {
  Wheel wheel_1;

  Axis axis = new Axis(wheel_1);
}


Class Wheel {
  int size;

  setSize(int size) {}
  int getSize() {}      
}
Run Code Online (Sandbox Code Playgroud)

现在我用车轮制造一辆汽车.然后从班级车我想构建一个轴.

为此,我将wheel_1传递给Axis的构造函数.

现在我的问题:我能否以某种方式确定Axis的构造函数不会改变wheel_1的大小,但是类车可以改变它.

Dun*_*nes 5

是的。通常这是通过使用类的复制构造函数来完成的Wheel

例如:

wheel_1 = new Wheel(wheel);
Run Code Online (Sandbox Code Playgroud)

请记住,Wheel该类需要以支持这一点的方式编写。也就是说,它应该提供一个复制构造函数。

注意:这并没有使对象 immutable。它只是生成了一个副本,您的班级以外的任何人都无法对其进行编辑。

如果您Wheel从任何其他方法返回实例,请务必在退出时防御性地复制它:

Wheel getWheel() {
  return new Wheel(wheel_1);
}
Run Code Online (Sandbox Code Playgroud)

最后,值得一提的是,只要有可能,创建不可变类总是一个好主意。那么也许您可以通过实际制作Wheel不可变来避免这个问题?


mab*_*aba 5

使Wheel类不可变.然后让对象在需要新大小时Car创建一个新Wheel对象.

public final class Wheel {
    private final int size;

    public Wheel(int size) {
        this.size = size;
    }

    public int getSize() {
        return size;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以毫无问题地将wheel对象传递给Axis.

public class Car {
    private Wheel wheel;
    private Axis axis;

    public Car(int initialWheelSize) {
        wheel = new Wheel(initialWheelSize);
        axis = new Axis(wheel);
    }
}
Run Code Online (Sandbox Code Playgroud)