修改克隆的对象

时间:2011-06-13 14:21:14

标签: java clone

我正在尝试修改帐户对象,但之后的更改似乎没有出现在原始列表中。也许有人可以查明错误。

请参阅以下代码:

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; 
} 

3 个答案:

答案 0 :(得分:1)

只需调用clone() 即可返回对象的深层副本。它将返回一个浅表副本。覆盖克隆是棘手的。按照Effective Java的约书亚布洛赫的建议,避免使用clone()支持复制构造函数。

private Account(Account account) { 
   this.name = account.getName();
   //etc
}

public void createCopy(Account account) { 
    return new Account(account);
}

另外,为什么不在帐户中存储帐户集合,因此在复制之前不需要遍历N个帐户?你也想仔细阅读Brian的答案。

答案 1 :(得分:0)

在这种情况下,您应该获得该帐户的副本(通过getAccount),修改它,然后将其重新插入列表

正如您所说,您正在修改副本。该副本本身并未连接到您的集合中,因此当您退出范围时,您将丢失它。

是否修改副本并重新插入副本是最佳解决方案。您可能希望在适当的位置进行修改,但这会让您对各种问题持开放态度(例如,线程 - 如果您修改帐户的一半而另一个客户端遍历列表并读取帐户详细信息会发生什么?)

答案 2 :(得分:0)

如果getAccount()返回您想要稍后修改的深度克隆,则应将其存储在变量中。如果不这样做,每次拨打getAccount()时都会收到一个新对象。