modifying cloned objects
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;
}
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 using clone()
in favor of a copy constructor.
private Account(Account account) {
this.name = account.getName();
//etc
}
public void createCopy(Account account) {
return new Account(account);
}
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.
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 (eg threading - what happens if you're halfway through modifying an account and another client traverses the list and reads the account details?)
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 call getAccount()
you are getting a new object.
上一篇: 对象克隆浅拷贝不会改变变量
下一篇: 修改克隆的对象