Java:对象克隆问题?

Java:对象克隆问题?,java,clone,Java,Clone,我有invoice对象,它有两个属性,productDescription和productQuantity,下面是代码: public类Invoice()实现可克隆 { 私有字符串描述; 私人产品数量; //接球手和接球手 公共对象克隆()引发CloneNotSupportedException{ 返回super.clone(); } } 现在我想在这个类上创建对象的副本 Invoice Invoice copy=(Invoice)Invoice.clone(); 现在,如果我更新了invo

我有
invoice
对象,它有两个属性,
productDescription
productQuantity
,下面是代码:

public类Invoice()实现可克隆
{
私有字符串描述;
私人产品数量;
//接球手和接球手
公共对象克隆()引发CloneNotSupportedException{
返回super.clone();
}
}
现在我想在这个类上创建对象的副本

Invoice Invoice copy=(Invoice)Invoice.clone();
现在,如果我更新了
invoiceCopy.setProductQuantity=10的值,那么
invoice
也会更新该值,但这不应该发生,有什么建议吗

更新代码
公共类发票实现可克隆{
私有字符串ProductDescription;
私人产品数量;
公共字符串getProductDescription(){
退货产品描述;
}
public void setProductDescription(字符串ProductDescription){
this.productDescription=productDescription;
}
public int getProductQuantity(){
退货数量;
}
公共无效集合产品数量(int i){
这个.productQuantity=i;
}
公共对象克隆()引发CloneNotSupportedException{
返回super.clone();
}
公共静态void main(字符串[]args){
发票=新发票();
发票。设置产品数量(10);
发票。SetProductDescription(“nike”);
发票发票副本=空;
试一试{
invoiceCopy=(发票)Invoice.clone();
}捕获(CloneNotSupportedException e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
发票副本。设置产品数量(20);
System.out.println(“发票数量:+Invoice.getProductQuantity());
System.out.println(“发票副本数量:
+invoiceCopy.getProductQuantity());
}
}

您只是调用
对象的
clone()
方法,该方法对您的类没有任何作用。您需要返回对象的新实例:

public class Invoice() implements Cloneable {
  private String productDescription;
  private int productQuantity;

  public Invoice() {

  }

  private Invoice(String productDescription, int productQuantity) {
    this.productDescription = productDescription; 
    this.productQuantity = productQuantity;

  //Getters & Setters

  public Object clone() throws CloneNotSupportedException {
     return new Invoice(productDescription, productQuantity);
  }
}

我添加了构造函数来传递参数。

默认克隆方法是一种肤浅的方法。 您必须为自己编写一个新方法或使用一个实现您所需的功能的库(参见apache的BeanUtils示例)

如果要编写,请尝试以下操作:

public class Invoice implements Cloneable {
private String productDescription;
private int productQuantity;

public Invoice() {
}

public Invoice(Invoice copy) {
    productDescription = copy.productDescription;
    productQuantity = copy.productQuantity;
}

public Object clone() throws CloneNotSupportedException {
    return new Invoice(this);
}

}

请展示一个简短但完整的程序来演示问题。我对克隆行为感到困惑,我想,如果我尝试更新我克隆的对象,那么它也会更新从中克隆对象的对象的属性,但上面运行了一个简单的示例,这与我的假设相矛盾。您的代码与克隆对象的预期工作完全一致。克隆将创建对象的副本,因此它实际上是一个新实例。由于对象的字段是不可变字符串和基元,因此原始对象和克隆之间没有引用。因此,在原始对象中看不到对克隆的更改。@马克:我这里的示例只是实际代码的表示,现在的问题是,如果克隆对象的属性发生了更改,那么这个差异也会反映在创建克隆的对象中,现在就开始调试问题,看看到底发生了什么…@Rachel:那么我建议你找一个实际演示这个问题的例子。默认的克隆方法在这里应该可以很好地解决这个问题-不管怎样,它都会做与你的构造函数相同的事情(除非它能确保它实际上是正确的类型)。@mabroukb这是一个糟糕的答案。默认克隆实现不仅要做同样的事情,还将破坏任何可能实现克隆的子类。我没有投反对票,但你肯定应该在这里投反对票。
clone()
的默认实现在只需要一个浅拷贝的情况下做了正确的事情(这里就是这种情况)。这将解决问题,因此我认为这里没有问题。如果您使用
Object.clone()
并使用对可变对象的引用,您可能会遇到很多麻烦。但是字符串或int都不是可变对象,因此默认的clone()方法将正常工作。这是正确的,但请考虑可修改性。一旦您以这种方式实现了它,并且在添加新字段时信任它,您就有可能遇到问题。我看不出有什么好处。@Stephan:是的,这里还有其他的事情发生——但是你的代码目前的状态对类没有帮助。任何通过构造函数编写浅层副本的人都会遇到完全相同的问题,如果事实证明在真实代码中“嵌入”了一个可变对象。