gpt4 book ai didi

java - 无法使用复制构造函数正确实例化新对象克隆

转载 作者:行者123 更新时间:2023-11-29 05:24:26 25 4
gpt4 key购买 nike

我正在尝试使用复制构造函数获取对象的克隆,不幸的是似乎对克隆的所有修改都反射(reflect)到原始对象。

我有这个界面

public interface Car{
public Car newInstance(Car c);
}

各种Object hat都是这样实现接口(interface)的

public FerrariSpyder implements Car{
String name;
String description
ArrayList<Feature> featureList;

public FerrariSpyder(String name, String description, ArrayList<Feature> featureList){
this.name=name;
this.descripion=descripion;
this.featureList=featureList;
}

@Override
public Car newInstance(Car c) {
return FerrariSpyder.newInstance((FerrariSpyder) c);
}

public static FerrariSpyder newInstance(FerrariSpyder fs) {
return new FerrariSpyder(fs.getName(), fs.getDescription(), fs.getFeatureList());
}

}

现在假设我有一个名为 originalCarCar 对象,我尝试用

克隆它
Car clone=originalCar.newIstance(originalCar);

如果我在克隆的 featureList 中添加元素,originalCar 中的 featureList 也会被修改。

最佳答案

您创建了对象的新实例,但字段是共享的。

关于namedescription,没有问题,因为Java把String当作不可变的。如果您尝试“修改”它们,您实际上会更改对它们的引用。

关于featureList,那就是另一回事了。您当前在两个对象中具有相同的列表实例。当您调用新对象的构造函数时,您需要创建列表的新实例,如下所示:

public static FerrariSpyder newInstance(FerrariSpyder fs) {
return new FerrariSpyder(fs.getName(), fs.getDescription(), new ArrayList<>(fs.getFeatureList()));
}

注意:注意,现在有 2 个列表,但它们共享相同的对象。这意味着两件事:

  • 如果您修改其中一个列表中的功能您将在另一个列表中看到该功能的修改。<
  • 如果您从一个列表中添加/删除对象,另一个列表将不受影响

如果您希望能够在不影响其他列表的情况下修改列表中的 Feature 对象,您还必须对这些对象进行深拷贝。


旁注:您在这里所做的基本上是编写一个clone() 方法,您将其命名为newInstance()。您可能应该实现 Cloneable 接口(interface)以使用 Java 方式进行操作 ;-)

关于java - 无法使用复制构造函数正确实例化新对象克隆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23248719/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com