如何使用 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();
}
}
我有以下代码。
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();
}
}