考虑以下两个类(一个是带有main()
方法的Main
):
VO 类:
public class TheVO {
private String[] theValues = null;
/**
*
*/
public TheVO(String[] theParam) {
this.theValues = theParam;
}
/**
*
* @return
*/
public String[] getValues(){
return this.theValues;
}
@Override
public String toString() {
StringBuffer buf = new StringBuffer("");
if(this.theValues == null){
return buf.toString();
}
for(String read:this.theValues){
buf.append(read);
buf.append(" ");
}
return buf.toString().trim();
}
}
主类:
public class Main {
/**
*
*/
public Main() {
super();
}
/**
* @param args
*/
public static void main(String[] args) {
TheVO theV = new TheVO(new String[]{"Hello","World!!"});
String[] vale = theV.getValues();
vale[0] = "Goodbye";
System.out.println(theV);
}
}
执行后结果:
再见世界!!
问题:
我知道 vale
数组变量指的是在构造函数中解析的同一个变量,如果我更改数组中的索引之一,它也会更改相同的 String[]。
如何“修复”或更改 TheVO 类以便我的结果是?:
Hello World !!
最佳答案
您需要使用防御性复制:在您的构造函数中复制 String[]
。这确保参数在传递给您的 VO 类后不会被修改。然后复制getter中的String[]
,避免getter的调用者修改你内部的String[]
。复制数组的最简单方法是调用 clone
:
this.theValues = theParam.clone();
如果你使用集合而不是数组,你可以通过使用 Collections.unmodifiableList()
包装你的集合来摆脱 getter 中的防御性副本。相反(这是一个更便宜的操作):
private List<String> theValues;
public List<String> getValues(){
return Collections.unmodifiableList(this.theValues);
}
不过,您仍然需要构造函数中的防御副本。
关于java - String[] 指向 VO 对象中的同一个引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5661078/