Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java克隆方法是如何工作的?_Java - Fatal编程技术网

Java克隆方法是如何工作的?

Java克隆方法是如何工作的?,java,Java,为什么Java返回学生对象而不是返回对象类对象。因为我们正在使用超级计算机。这是否意味着Java本身在clone方法中提供了浅层克隆?Java克隆是逐字段复制,即对象类不知道将调用clone()方法的类的结构 1) 如果类只有原始数据类型成员,则将创建对象的全新副本,并返回对新对象副本的引用 2) 如果类包含任何类类型的成员,则只复制对这些成员的对象引用,因此原始对象和克隆对象中的成员引用都引用同一对象 请参阅此链接,根据clone()fromObject生成调用对象的“浅”副本 如果要实现cl

为什么Java返回学生对象而不是返回对象类对象。因为我们正在使用超级计算机。这是否意味着Java本身在clone方法中提供了浅层克隆?

Java克隆是
逐字段复制
,即对象类不知道将调用clone()方法的类的结构

1) 如果类只有原始数据类型成员,则将创建对象的全新副本,并返回对新对象副本的引用

2) 如果类包含任何类类型的成员,则只复制对这些成员的对象引用,因此原始对象和克隆对象中的成员引用都引用同一对象

请参阅此链接,根据
clone()
from
Object
生成调用对象的“浅”副本

如果要实现
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();
   }
}