我正在尝试修改帐户对象,但之后的更改似乎没有出现在原始列表中 . 也许有人可以查明错误 .
看下面的代码:
if(aBank.getAccount(number)!=null){
System.out.println("Account information is listed below");
System.out.println(aBank.getAccount(number).toString());
System.out.println("Modify first name y or n");
answer=keyboard.nextLine();
if(answer.equals("Y")||answer.equals("y")){
System.out.println("Enter first name:");
firstName=keyboard.nextLine();
aBank.getAccount(number).getCustomer().setFirstName(firstName);
}
System.out.println("Modify last name y or n");
answer=keyboard.nextLine();
if(answer.equals("Y")|| answer.equals("y")){
System.out.println("Enter last name:");
lastName=keyboard.nextLine();
aBank.getAccount(number).getCustomer().setLastName(lastName);
}
}
else{
System.out.println("Account not found");
}
注意:getAccount(number)返回帐户的副本,这是一个深层副本,getCustomer也返回一个深层副本的克隆
Contents of getAccount
public Account getAccount(long accountNumber ) throws Exception {
boolean found=false;
for(int i=0;i<accounts.size();i++){
if(accounts.get(i).getAccountNumber().compareTo(accountNumber)==0){
found=true;
return accounts.get(i).clone();
}
}
if (!found){
return null;
}
return null;
}
3 回答
只需调用
clone()
将 not 返回对象的深层副本 . 它将返回一个浅拷贝 . 覆盖克隆是棘手的 . 按照Effective Java的Joshua Bloch的建议,避免使用clone()
支持复制构造函数 .另外,为什么不在 Map 中存储帐户集合,因此在复制之前不需要遍历N个帐户?你也想仔细阅读Brian的答案 .
在这种情况下,您应该获得该帐户的副本(通过
getAccount
),修改它,然后将其重新插入列表中 .正如您所指出的,您正在修改副本 . 该副本本身并未连接到您的集合中,因此当您退出范围时,您将丢失它 .
是否修改副本并重新插入副本是最佳解决方案 . 您可能希望在适当的位置进行修改,但这会让您对各种问题持开放态度(例如,线程化 - 如果您修改帐户的一半而另一个客户端遍历列表并读取帐户详细信息会发生什么?)
如果
getAccount()
返回稍后要修改的深度克隆,则应将其存储在变量中 . 如果不这样做,每次调用getAccount()
时都会得到一个新对象 .