如何使用 java 中的 getter 保护 class 中的私有字段

How to protect private field in class with getter in java

我有以下代码。

public class GetterTest {

    public static void main(String[] args) {
        Car car = new Car();

        StringBuilder wheel = car.getWheel();
        wheel.append("asd");

        System.out.println(car.getWheel());
    }
}

class Car {

    private StringBuilder wheel;

    public Car() {
        wheel = new StringBuilder("a");
    }

    public StringBuilder getWheel() {
        return wheel;
    }

    public void setWheel(StringBuilder wheel) {
        this.wheel = wheel;
    }

}

这里的问题是即使我有一个 getter 它也不保护变量并且在使用它之后它被改变了。如何更好的保护变量?

您不应该 return StringBuilder 而是值。这将创建一个新的 String,它不再连接到您的支持 StringBuilder

public String getWheel() {
    return wheel.toString();
}

但是如果你真的想要 return 一个 StringBuilder,你可以用当前的数据创建一个新的,基本上断开两个实例:

public StringBuilder getWheel() {
    return new StringBuilder(wheel.toString());
}

StringBuilder 变量不适合 getter。 getter returns 当前 String 那个 StringBuilder 的值会更有意义,因为 String 它是不可变的:

public String getWheel() {
    return wheel.toString();
}

setter 也应该更改,因为当前的实现允许 setter 的调用者改变传递给 setter 的 StringBuilder,从而改变成员在调用 setter 之后。

public void setWheel (String wheel)
{
    this.wheel = new StringBuilder (wheel);
}

在您要保护的字段中getter您可以克隆该字段而不是返回当前字段。

public void doSomething() {
    Car car = new Car();

    Wheel wheel = car.getWheel();
    wheel.getaVariable().append("asd");

    System.out.println(car.getWheel());
}

public class Car {
    private Wheel wheel;

    public Car() {
        wheel = new Wheel();
    }

    public Wheel getWheel() {
        Wheel output = null;
        try {
            output = wheel.clone();
        } catch (CloneNotSupportedException e) {
            // Manage exception
        }
        return output;
    }

    public void setWheel(Wheel wheel) {
        this.wheel = wheel;
    }
}

public class Wheel implements Cloneable {
    private StringBuilder aVariable;

    public Wheel() {
        aVariable = new StringBuilder("a");
    }

    public StringBuilder getaVariable() {
        return aVariable;
    }

    public void setaVariable(StringBuilder aVariable) {
        this.aVariable = aVariable;
    }

    @Override
    protected Wheel clone() throws CloneNotSupportedException {
        Wheel clone = (Wheel) super.clone();
        clone.setaVariable(new StringBuilder(aVariable));
        return clone;
    }

    @Override
    public String toString() {
        return aVariable.toString();
    }
}