我正在学习java。这是我编写的代码,作为理解如何在java中克隆对象的一部分...
Class Address {
String city;
String state;
}
class Customer implements Cloneable {
String name;
Address address;
public Customer(String name, String city, String state) {
this.name = name;
address = new Address();
address.city = city;
address.state = state;
}
public Object clone() {
Customer coned = null;
try {
cloned = super.cloned();
return cloned;
} catch(CloneNotSupportedException e) {
return null;
}
}
}
这里我想克隆一个Customer对象,如下所示 -
Customer customer = new Customer("john", "acity", "astate");
Customer newCustomer = (Customer) customer.clone();
newCustomer.address.city = "bcity";
这就是问题所在。一旦我为city
设置了新值,它实际上也会更新原始对象。我的目标是将Customer
对象的所有内容复制到一个新对象,以便我可以安全地修改新对象而不会影响原始对象。
为此,我修改了clone
类的Customer
方法 -
public Object clone() {
Customer coned = null;
try {
cloned = super.cloned();
clone.address = (Address) address.clone();
return cloned;
} catch(CloneNotSupportedException e) {
return null;
}
}
这是更新的地址类 -
class Address {
String city;
String state;
public Object clone()
throws CloneNotSupportedException
{
return super.clone();
}
}
任何人都可以帮助我了解错误克隆的原因是什么address
对象
答案 0 :(得分:1)
好的,首先:请将IDE中的确切代码复制粘贴到您的问题中。你的代码中仍有一些问题会阻止它编译,确实复制它比输入它要容易得多吗?
你遇到的关键问题很简单:你什么都不做。您唯一要做的就是在整个层次结构中调用super.clone()
,这最终会导致Object.clone()
被调用(这对您的自定义类中的字段没有任何影响)。
解决方案?在clone()
方法中添加实际的克隆逻辑。
您可以使用Cloneable
接口继续传统路由并创建它,但是当您可以使用可用的构造函数创建对象的新实例时,实际上并不需要这样做,这将立即切断两个对象之间的每个关系(除了具有相等的值)。
您必须记住的是为每个引用类型创建一个新实例,该实例作为当前图层中的字段保存。
如果您正在处理多个图层(继承),那么您必须记得事先致电super.clone()
并实施clone()
方法。
它是如何工作的?很简单,请考虑以下代码段:
public class Main {
public static void main(String[] args) {
Customer jack = new Customer("Jack", "Jackson");
jack.setBalance(9001);
Customer john = jack.clone();
john.setBalance(1337);
System.out.println("Jack's balance (name = " + jack.getFirstname()
+ "): " + jack.getBalance());
System.out.println("John's balance (name = " + john.getFirstname()
+ "): " + john.getBalance());
}
}
class Customer {
private String firstname, lastname;
private int balance;
public Customer(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
balance = 500;
}
public String getFirstname() {
return firstname;
}
public String getLastname() {
return lastname;
}
public int getBalance() {
return balance;
}
public void setBalance(int b) {
this.balance = b;
}
protected Customer clone() {
Customer newCustomer = new Customer(getFirstname(), getLastname());
newCustomer.setBalance(getBalance());
return newCustomer;
};
}
此输出结果如下:
杰克的余额(姓名=杰克):9001
约翰的余额(姓名=杰克):1337