public class Student implements Cloneable {
public Student clone() {
Student clonedStudent = (Student) super.clone();
return clonedStudent;
}
}
为什么Java返回student对象而不是返回对象类对象。因为我们正在使用超级。这是否意味着Java本身在克隆方法中提供浅层克隆?
答案 0 :(得分:13)
java cloning是field by field copy
,即因为Object类不知道将调用clone()方法的类的结构。
1)如果该类具有仅原始数据类型成员,则将创建该对象的全新副本,并且将返回对新对象副本的引用
2)如果类包含任何类类型的成员,则只复制对这些成员的对象引用,因此原始对象和克隆对象中的成员引用引用相同的对象。
请参阅此链接object cloning in java
答案 1 :(得分:9)
了解docs对此的评价:
...因此,此方法执行此对象的“浅拷贝”,而不是a “深层复制”操作。
另见this link:
如果类只有原始数据类型成员那么完全 将创建对象的新副本并引用新的 将返回对象副本。但是,如果该类包含成员 任何类类型然后只有对象引用那些成员 复制并因此将原始对象中的成员引用为 以及克隆的对象引用同一个对象。
答案 2 :(得分:4)
clone()
方法就像一个复制构造函数。
它创建并返回对象的副本。
由于对象类具有克隆方法(受保护),因此您无法在所有类中使用它。要克隆的类应该实现克隆方法并覆盖它。它应该为复制提供自己的意义,或者至少它应该调用super.clone()
。此外,您必须实现Cloneable标记接口,否则您将获得CloneNotSupportedException。当你调用super.clone()
时,你依赖于Object类的实现,你得到的是一个浅拷贝。
您可以提供Wiki Page以获得更多理解。
对于克隆对象,应该实现接口Cloneable
如果您尝试在未实现Cloneable
接口的类中使用clone方法,则会抛出CloneNotSupportedException
。
答案 3 :(得分:0)
根据来自clone()
的{{3}} Object
生成对象所在的“浅层”副本。
如果您正在实现clone()
,那么约定是您从super.clone()
获得初始副本,然后实现修改此返回对象的其余克隆操作。
答案 4 :(得分:0)
java.lang.Object在Java中提供了clone()方法的默认实现。它在Object类中声明为受保护和本机,因此在本机代码中实现。由于它通过调用super.clone()方法返回对象的clone()的约定,所以任何克隆过程最终都会到达java.lang.Object clone()方法。此方法首先检查相应的对象是否实现了Cloneable接口,这是一个标记接口。如果该实例没有实现Cloneable,那么它会在Java中抛出CloneNotSupportedException,这是一个经过检查的异常,在克隆对象时总是需要处理它。 在java中,如果一个类需要支持克隆,则必须执行以下操作:
A)您必须实现Cloneable接口。 B)您必须从Object类重写clone()方法。 [有点奇怪。 clone()方法应该在Cloneable接口中。]
下面给出了关于clone()方法的Java文档(格式化和提取)。 / * 创建并返回此对象的副本。 " copy"的确切含义可能取决于对象的类。 一般意图是,对于任何对象x,表达式: 1)x.clone()!= x将为真//保证克隆对象将具有单独的内存地址分配。 2)x.clone()。getClass()== x.getClass()将为true,但这些不是绝对要求。原始对象和克隆对象应该具有相同的类类型,但它不是必需的。 3)x.clone()。equals(x)将为true,这不是绝对要求。原始和克隆对象应该使用equals()方法相等,但它不是必需的。 * /
让我们看一个例子:
public class MyClone {
int x;
public static void main(String[] args) throws
CloneNotSupportedException {
MyClone c = new MyClone();
MyClone a = (MyClone) c.clone(); // Type-cast is required
}
}
因为clone()是Object类的一部分,而Object不会实现Cloneable接口,所以当我们自己的类不实现Cloneable接口时,JVM将不知道这个类是否有资格进行克隆,所以CloneNotSupportedException出来了。
当我们说MyClone a =(MyClone)c.clone();时,只有两件事是可能的:
它将返回克隆的对象。
或者它会抛出CloneNotSupportedException。
很明显,当你想要克隆对象时,不必在你的类中实现clone(),如果你不这样做,Object中的clone()方法被声明为protected - 只有子类和同一个包的成员将能够在该对象上调用clone()。如果你想改变它,你应该覆盖它并公开它。
在clone()方法调用之前检查:
if(c instanceof Cloneable) {
MyClone a = (MyClone) c.clone();
}
注意:调用clone()时不会调用构造函数。我们有责任正确设置该类的所有成员变量。
实施
Room.java
public class Room {
private String roomSize;
public Room(String roomSize){
this.roomSize = roomSize;
}
//Any Getters-Setters goes here
}
Flat.java
public class Flat implements Cloneable {
private String flatNumber;
private Room room;
public Flat(String size,Room room){
this.size = size;
this.room = room;
}
public Object clone() {
try {
return (Flat)super.clone();
}
catch (CloneNotSupportedException e) {
System.out.println("CloneNotSupportedException comes out : "
+e.getMessage());
}
}
//Any Getters-Setters goes here
}
Main.java
public class Main {
public static void main(String[] args) {
Room room = new Room("40 X 40");
Flat flat1 = new Flat(403 , room);
Flat flat2 = (Flat)flat1.clone();
}
}
这里super.clone()在clone()中被调用。我们知道,clone()在Object中声明,因此它被每个Java对象继承。调用super.clone()复制我们的超类'字段并制作字段的按位副本。这称为浅拷贝,这意味着当您使用clone()复制Flat时,字段的flatNumber将被复制其各自的值,但是空间被引用复制 - 逐位复制,内存地址被复制。
您对原始对象的空间所做的任何更改都将反映在克隆对象中,反之亦然。要解决这个问题,我们需要深层复制。现在,我们需要更改Room类,并实现" Cloneable" interface和clone()方法,然后在Flat对象的clone()方法中调用Room对象的clone()方法。
新实施
Room.java
public class Room {
private String roomSize;
public Room(String roomSize){
this.roomSize = roomSize;
}
public Object clone() {
try {
return (Room)super.clone();
}
catch (CloneNotSupportedException e) {
System.out.println("CloneNotSupportedException comes out : "
+e.getMessage());
}
}
//Any Getters-Setters goes here
}
Flat.java
public class Flat implements Cloneable {
private String flatNumber;
private Room room;
public Flat(String size,Room room){
this.size = size;
this.room = room;
}
public Object clone() {
Flat flat = null;
try {
flat = (Flat)super.clone();
}
catch (CloneNotSupportedException e) {
System.out.println("CloneNotSupportedException comes out : "
+e.getMessage());
}
flat.room = (Room) room.clone();
return flat;
}
//Any Getters-Setters goes here
}
Main.java
public class Main {
public static void main(String[] args) {
Room room = new Room("40 X 40");
Flat flat1 = new Flat(403, room);
Flat flat2 = (Flat)flat1.clone();
}
}
我希望这能更好地理解克隆及其实现。
感谢http://interviewguess.blogspot.in/2017/02/how-does-clone-method-work.html