就"最佳实践"而言,哪种方法适用于创建对象的"深层复制"?
我阅读了很多有关对象的clone()方法和可克隆接口的线程,但我找不到我的问题的合法答案。长话短说:
我发现 Object 有一个方法 clone() ,它可以“神奇地”克隆你的对象。但是,如果不实现 Cloneable 接口,则无法使用该方法,因为该接口允许 Object 使用clone() 方法。那么他们为什么要这么做呢?为什么每个对象不应该从一开始就可以克隆?
我想克隆一个给定的对象.
如果我这样做
public class Something{
Object o; //set in the constructor
public Something(Object o){
this.o = o;}
public Something clone() throws CloneNotSupportedException{
Something temp = super.clone();
if (o instanceof Cloneable) //important part
temp.o = o.clone(); //important part
else temp.o = o;
}
}
Run Code Online (Sandbox Code Playgroud)
这是行不通的,因为o.clone()受到保护.
如果我这样做
if (o instanceof Cloneable) //important part
temp.o = ((Cloneable)o).clone(); //important part
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为Cloneable是一个空接口.
那么我如何说服编译器你可以克隆o?
我正在使用js/jQuery并尝试创建一个真正的克隆 - 我目前正在使用jQuery.我希望在多级对象中甚至可以对子对象进行深度克隆,但事实并非如此.下面是我的测试代码和输出,让我相信jQuery的深度克隆实际上并没有克隆所有的子对象.
有没有人写过真正的深度克隆函数,或者有没有办法使jQuery的工作符合预期?
码:
function deepClone (obj) {
return $.extend(true, {}, obj);
};
var orig = {};
orig.companyData = {};
orig.companyData.TEST= 1;
var deep1 = deepClone(orig);
deep1.companyData.TEST= 0;
var deep2 = deepClone(orig);
console.log("orig: " + orig.companyData.TEST);
console.log("deep1: " + deep1.companyData.TEST);
console.log("deep2: " + deep2.companyData.TEST);
Run Code Online (Sandbox Code Playgroud)
控制台输出:
注意:我期望1,0,1
0
0
0
Run Code Online (Sandbox Code Playgroud) public class Color {
String color;
Color(String color)
{
this.color=color;
}
}
public class ColoredCircle {
int x;
Color color;
ColoredCircle(int x, Color color)
{
this.x=x;
this.color=color;
}
public Object testClone()
{
Color c = new Color(this.color.color);
ColoredCircle cc1 = new ColoredCircle(this.x, c);
return cc1;
}
}
Run Code Online (Sandbox Code Playgroud)
在上面提到的ColoredCircle类中,我们有一个名为testClone()的方法,它与Deep Cloning完全相同.现在我很困惑,有必要实现Cloneable克隆吗?以上程序是一种深度克隆吗?
class Person implements Cloneable {
String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
}
Person p1 = new Person();
p1.setFirstName("P1 Sara");
Person p3 = new Person();
try {
p3 = (Person) p1.clone();
} catch (CloneNotSupportedException e) {
}
p3.setFirstName("cloned Sara");
System.out.println("P3 : " + p3.getFirstName());
System.out.println("P1: " + p1.getFirstName());
Run Code Online (Sandbox Code Playgroud)
我读过 clone() 方法实际上是一种浅拷贝。因此,我假设当 P3 中某个字段的值发生变化时,P1 中的值也会发生变化。但是,那没有发生。我在这里缺少什么?
如果我克隆以下类的实例,并在实例化时覆盖一个方法,克隆是否具有覆盖的方法?我在https://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html和https://docs.oracle.com/javase/7/ 中都没有发现任何关于这种行为的信息 docs/api/java/lang/Object.html#clone() 。
public class ToBeCloned implements Cloneable{
public int returnInt() {
return 1;
}
public void printTest() {
System.out.println("returnInt():"+returnInt()+"\nToBeCloned Original");
}
@Override
public ToBeCloned clone() throws CloneNotSupportedException {
return (ToBeCloned) super.clone();
}
}
Run Code Online (Sandbox Code Playgroud) Object[] o = new Object[]{};
System.out.println(o instanceof Cloneable);
Run Code Online (Sandbox Code Playgroud)
这表示为o/p.我不明白为什么?
我正在尝试实现一个clone()方法DoubleLinkedList.现在,问题是通过"约定"实现它比创建一个新的DoubleLinkedList并且用我当前的DoubleLinkedList的所有元素填充它要麻烦得多.
这样做有什么不方便吗?
这是我目前的做法:
@Override
public DoubleLinkedList<T> clone() {
DoubleLinkedList<T> dll = new DoubleLinkedList<T>();
for (T element : dll) {
dll.add(element);
}
return dll;
}
Run Code Online (Sandbox Code Playgroud)
以下是大会的内容:
@Override
public DoubleLinkedList<T> clone() {
try {
DoubleLinkedList<T> dll = (DoubleLinkedList<T>)super.clone();
//kinda complex code to copy elements
return dll;
} catch (CloneNotSupportedException e) {
throw new InternalError(e.toString());
}
}
Run Code Online (Sandbox Code Playgroud) public class test implements Cloneable {
@Override
public test clone() {
return (test) super.clone();
}
public static void main(String[] args) {
new test().clone();
}
}
Run Code Online (Sandbox Code Playgroud)
error: unreported exception CloneNotSupportedException当我尝试编译时(第4行,而不是主要部分),我得到了.据我所知,实现的整个目的Cloneable是摆脱异常.
super.clone()而不抛出或捕获异常?cloneable ×10
java ×9
clone ×6
cloning ×2
deep-copy ×2
interface ×2
arrays ×1
instanceof ×1
javascript ×1
jquery ×1