修改克隆对象
我正在尝试修改帐户对象,但更改似乎随后没有出现在原始列表中。也许有人可以指出错误。
请参阅下面的代码:
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;
}
I am trying to modify account objects but the changes do not seem to appear in the original list afterward. Perhaps someone can pinpoint an error.
see code below:
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");
}
note: getAccount(number) returns a clone of the account which is a deep copy and getCustomer also returns a clone which is a deep copy
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
简单地调用
clone()
将不会返回对象的深层副本。它将返回一个浅副本。覆盖克隆是很棘手的。遵循 Effective Java 中 Joshua Bloch 的建议,避免使用clone( )
支持复制构造函数。另外,为什么不将 Accounts 集合存储在 Map 中,这样在复制之前就不需要遍历 N 个 Accounts 了?您还需要仔细阅读布莱恩的回答。
Simply invoking
clone()
will not return a deep copy of an object. It will return a shallow copy. Overriding clone is tricky. Follow Joshua Bloch's advice from Effective Java and avoid usingclone()
in favor of a copy constructor.Also, why not store the collection of Accounts in a Map, so you do not need to traverse N accounts before you copy? You'll also want to read Brian's answer closely.
在这种情况下,您应该获取帐户的副本(通过
getAccount
),对其进行修改,然后将其重新插入列表。正如您所指出的,您正在修改副本。该副本本身并未连接到您的集合中,因此当您退出范围时您将丢失它。
修改副本并重新插入它是否是最佳解决方案是另一回事。您可能想要就地修改,但这会让您面临各种问题(例如,线程 - 如果您修改帐户的过程中,另一个客户端遍历列表并读取帐户详细信息,会发生什么?)
In this scenario you should get a copy of the account (via
getAccount
), modify it, and then reinsert it into the list.As you've noted, you're modifying a copy. That copy itself is not wired into your collection and so you'll lose it when you exit scope.
Whether modifying a copy and reinserting it is the optimal solution is another matter. You may want to modify in place, but that leaves you open to all sorts of issues (e.g. threading - what happens if you're halfway through modifying an account and another client traverses the list and reads the account details?)
如果
getAccount()
返回您想要稍后修改的深层克隆,则应将其存储在变量中。如果不这样做,每次调用getAccount()
时,您都会获得一个新对象。If
getAccount()
returns a deep clone that you want to modify later, you should store it in a variable. If you don't, everytime you callgetAccount()
you are getting a new object.