考虑以下两个类(一个是带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
数组变量是指在构造函数中解析的同一个变量,如果我更改了数组中的一个索引,它会在VO中更改相同的String[]
。
如何“修复”或更改TheVO类,以便我的结果是?:
Hello World !!
答案 0 :(得分:2)
您需要使用防御性复制:复制构造函数中的String[]
。这可确保在将参数传递给您的VO类后不会修改该参数。然后复制getter中的String[]
以避免getter的调用者修改内部String[]
。复制arrray的最简单方法是调用clone
:
this.theValues = theParam.clone();
如果你使用集合而不是数组,你可以通过使用Collections.unmodifiableList()
包装你的集合来取消getter中的防御副本(这是一个便宜得多的操作):
private List<String> theValues;
public List<String> getValues(){
return Collections.unmodifiableList(this.theValues);
}
尽管如此,你仍然需要构造函数中的防御性副本。
答案 1 :(得分:1)
您可以在getValues()方法中复制(或克隆)String []。
这样,通过创建一个新数组,就会失去String数组之间的耦合。
答案 2 :(得分:1)
您可以尝试更改getValues();返回TheVO.theValues数组副本的方法,而不是对原始数组的引用。
答案 3 :(得分:1)
我建议从TheVO.getValues()
返回时执行内部数组的副本。如果您在Java 1.6上运行,则可以使用Arrays.copyOf()
方法。
public String[] getValues() {
return Arrays.copyOf(theValues, theValues.length);
}
请注意,无需使用this
来访问此处的实例字段。
答案 4 :(得分:1)
在VO构造函数
中创建数组的副本答案 5 :(得分:1)
更改getValues()方法以克隆数组...
像这样......
public String[] getValues(){
return this.theValues.clone();
}