【发布时间】:2011-08-13 17:06:50
【问题描述】:
为什么我们在 Java 中使用clone() 方法? (请给出关于内存限制的答案。)这会减少内存使用吗?如果是,那么如何?这会减少内存泄漏的影响吗?
【问题讨论】:
-
我们没有。 18 年来我从未使用过它,或者“复制构造函数”。
为什么我们在 Java 中使用clone() 方法? (请给出关于内存限制的答案。)这会减少内存使用吗?如果是,那么如何?这会减少内存泄漏的影响吗?
【问题讨论】:
clone() 将一个对象的值复制到另一个对象。 clone() 方法为创建对象的精确副本节省了额外的处理任务。
正如您在下面的示例中看到的,两个引用变量具有相同的值。
class Student18 implements Cloneable {
int rollno;
String name;
Student18(int rollno, String name) {
this.rollno = rollno;
this.name = name;
}
public static void main(String args[]) {
try {
Student18 s1 = new Student18(101, "amit");
Student18 s2 = (Student18) s1.clone();
System.out.println(s1.rollno + " " + s1.name);
System.out.println(s2.rollno + " " + s2.name);
} catch (CloneNotSupportedException c) {
}
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
输出:
101 amit
101 amit
如果我们通过new关键字创建另一个对象并将另一个对象的值分配给这个对象,则需要对该对象进行大量处理。所以为了节省额外的处理任务,我们使用 clone() 方法。
【讨论】:
如果我们需要使用许多具有相同数据的对象,那么不要使用 new 关键字创建对象。使用 clone 方法创建该对象,因为使用 clone 方法创建对象的操作比使用 new 关键字更快。
【讨论】:
除了不要使用克隆,实现一个复制构造函数,你问过内存限制。
克隆的想法是创建克隆对象的精确副本。因此,在最坏的情况下,您之后会使用两倍的内存量。实际上 - 少一点,因为字符串经常被实习并且(通常)不会被克隆。即使这取决于克隆方法/复制构造函数的实现者。
这是一个带有复制构造函数的类的简短示例:
public class Sheep {
private String name;
private Fur fur;
private Eye[2] eyes;
//...
// the copy constructor
public Sheep(Sheep sheep) {
// String already has a copy constructor ;)
this.name = new String(sheep.name);
// assuming Fur and Eye have copy constructors, necessary for proper cloning
this.fur = new Fur(sheep.fur);
this.eyes = new Eye[2];
for (int i = 0; i < 2; i++)
eyes[i] = new Eye(sheep.eyes[i]);
}
}
用法:
Sheep dolly = getDolly(); // some magic to get a sheep
Sheep dollyClone = new Sheep(dolly);
【讨论】:
Animal,它也有需要调用的属性。复制构造函数方法是否意味着 both Animal 和 Sheep 都有复制构造函数,而 Sheep CC 必须调用 super(sheep)?
super(sheep);,超类将基于该实例初始化其字段。无论如何,您都需要调用超类的(一个)构造函数。
复制一个对象起初似乎是一项简单的任务:
只需将所有属性的值复制到同一类的另一个实例中。 但是引用其他对象的变量呢?这些参考值的副本意味着它们将指向与第一个类相同的对象。
但这也许不是我们想要的。也许我们希望副本引用的所有对象也都是独立副本。
这两种类型的对象副本被称为:
浅拷贝 - 原始对象所有属性的精确位拷贝 深度复制 - 原语被精确复制,但被引用的对象被复制而不是引用本身。 所有 Java 类都继承的 Object 类包括 clone() 方法,该方法将对所有属性进行精确的位复制。
但是,clone() 是一种受保护的方法。因此,给定对象不能被包外任何类的实例克隆(除非它们是该对象类的子类)。这允许类设计器明确指定要制作的克隆类型(浅或深)。
Java 需要想要覆盖 clone() 方法的类来实现可克隆接口。 clone() 方法必须公开,以便覆盖访问限制。
例如,HashTable 类实现可克隆。它的 clone() 方法进行了浅拷贝,因此复制的 HashTable 的键和值将引用与原始对象相同的对象。
但是,许多核心 Java 类不实现可克隆。如果为此类类调用 clone() 方法,则会导致 CloneNotSupportedException。
【讨论】:
我们应该避免使用 clone() Here 就是很好的例子
【讨论】:
简而言之,它用于复制对象而不是引用,它增加了内存使用量。
【讨论】:
我们应该不使用它。 It is a broken and obsolete idiom,在新代码中应避免使用。最好尽可能使用复制构造函数。
【讨论】: