Java克隆方法是如何工作的?
为什么Java返回学生对象而不是返回对象类对象。因为我们正在使用超级计算机。这是否意味着Java本身在clone方法中提供了浅层克隆?Java克隆是Java克隆方法是如何工作的?,java,Java,为什么Java返回学生对象而不是返回对象类对象。因为我们正在使用超级计算机。这是否意味着Java本身在clone方法中提供了浅层克隆?Java克隆是逐字段复制,即对象类不知道将调用clone()方法的类的结构 1) 如果类只有原始数据类型成员,则将创建对象的全新副本,并返回对新对象副本的引用 2) 如果类包含任何类类型的成员,则只复制对这些成员的对象引用,因此原始对象和克隆对象中的成员引用都引用同一对象 请参阅此链接,根据clone()fromObject生成调用对象的“浅”副本 如果要实现cl
逐字段复制
,即对象类不知道将调用clone()方法的类的结构
1) 如果类只有原始数据类型成员,则将创建对象的全新副本,并返回对新对象副本的引用
2) 如果类包含任何类类型的成员,则只复制对这些成员的对象引用,因此原始对象和克隆对象中的成员引用都引用同一对象
请参阅此链接,根据clone()
fromObject
生成调用对象的“浅”副本
如果要实现clone()
,约定是从super.clone()
获取初始副本,然后执行其余的克隆操作,修改此返回的对象。请参见下面的说明:
。。。因此,此方法执行此对象的“浅复制”,而不是复制
“深度复制”操作
另见:
如果类只有基元数据类型成员,则
将创建对象的新副本,并引用新副本
将返回对象副本。但是,如果类包含
任何类类型,则只有对这些成员的对象引用是
已复制,因此成员引用在原始对象和
以及克隆对象引用相同的对象
clone()
方法的作用类似于复制构造函数
它创建并返回对象的副本。
由于对象类具有克隆方法(受保护),因此不能在所有类中使用该方法。要克隆的类应该实现clone方法并覆盖它。它应该为copy提供自己的含义,或者至少应该调用super.clone()
。此外,您还必须实现可克隆标记接口,否则您将获得CloneNotSupportedException。调用super.clone()
时,依赖于对象类的实现,得到的是一个浅拷贝
你可以参考更多的了解
对于克隆对象,应实现接口Cloneable
如果您试图在未实现
Cloneable
接口的类中使用clone方法,它将抛出CloneNotSupportedException
java.lang.Object
提供java中clone()
方法的默认实现。它在对象
类中声明为受保护且本机,因此在本机代码中实现。由于其惯例是通过调用super.clone()
方法返回对象的clone()
,因此任何克隆过程最终都会到达java.lang.object
clone()
方法。此方法首先检查对应对象是否实现了Cloneable
接口,该接口是一个标记接口。如果该实例没有实现Cloneable,那么它会抛出Java中的CloneNotSupportedException
,一个选中的异常,在克隆对象时总是需要处理该异常。
在java中,如果类需要支持克隆,则必须执行以下操作:
A) 您必须实现Cloneable
接口。
B) 您必须从对象
类重写clone()
方法。[这很奇怪。clone()
方法应该在Cloneable
界面中。]
下面给出了有关clone()
方法的Java文档(格式化和解压缩)。
/*
创建并返回此对象的副本。“复制”的确切含义可能取决于对象的类别。
一般目的是,对于任何对象x
,表达式:
1) x.clone()!=x
将为true//保证克隆对象将具有单独的内存地址分配。
2) x.clone().getClass()==x.getClass()
将为真,但这些不是绝对要求//原始对象和克隆对象应具有相同的类类型,但不是强制要求。
3) x.clone().equals(x)
将为真,这不是绝对要求//使用equals()
方法应该使原始对象和克隆对象相等,但这不是强制性的。
*/
让我们看一个例子:
public class Student implements Cloneable {
public Student clone() {
Student clonedStudent = (Student) super.clone();
return clonedStudent;
}
}
由于clone()
是Object
类的一部分,并且Object
不会实现Cloneable
接口,当我们自己的类不会实现Cloneable
接口时,JVM将不知道该类符合克隆条件,因此,CloneNotSupportedException
出现了
当我们说MyClone a=(MyClone)c.clone()时,只有两件事是可能的代码>:
它将返回克隆的对象
或者它将抛出CloneNotSupportedException
很明显,当您想要克隆对象时,在类中实现clone()
不是强制性的,如果您不这样做,则object
类中的clone()
方法被声明为protected-只有同一包的子类和成员才能在对象上调用clone()
。如果你想改变它,你应该覆盖它并将其公开
在clone()
方法调用之前进行检查:
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()
时,不会调用任何构造函数。正确设置该类的所有成员变量是我们的责任
实施:
if(c instanceof Cloneable) {
MyClone a = (MyClone) c.clone();
}
这里super.clone()
在clone()
内部被调用。我们知道,clone()Room.java
public class Room {
private String roomSize;
public Room(String roomSize){
this.roomSize = roomSize;
}
//Any Getters-Setters go 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 go 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();
}
}
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 go 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 go 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();
}
}