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.

链接地址: http://www.djcxy.com/p/6966.html

上一篇: 对象克隆浅拷贝不会改变变量

下一篇: 修改克隆的对象