修改克隆的对象
我正在尝试修改帐户对象,但这些更改似乎未出现在原始列表中。 也许有人可以指出一个错误。
见下面的代码:
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也返回深层副本的副本
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;
}
简单地调用clone()
将不会返回对象的深层副本。 它会返回一个浅拷贝。 覆盖克隆是棘手的。 按照Joshua Bloch的Effective Java建议,避免使用clone()
来支持复制构造函数。
private Account(Account account) {
this.name = account.getName();
//etc
}
public void createCopy(Account account) {
return new Account(account);
}
另外,为什么不将帐户集合存储在地图中,因此在复制之前您不需要遍历N个帐户? 你也想仔细阅读Brian的答案。
在这种情况下,您应该获得该帐户的副本(通过getAccount
),对其进行修改,然后将其重新插入到列表中。
如您所知,您正在修改副本。 该副本本身没有连接到您的收藏中,因此当您退出范围时您将失去它。
无论是修改副本还是重新插入副本,最佳解决方案都是另一回事。 您可能希望进行适当的修改,但这会让您面对各种问题(例如线程 - 如果您在修改帐户的过程中遇到了另一个客户端,并且会读取帐户详细信息,会发生什么情况?)
如果getAccount()
返回一个稍后要修改的深度克隆,则应将其存储在一个变量中。 如果你不这样做,每次调用getAccount()
你都会得到一个新的对象。