"directly assigning the class object to another object of same class" 和 "using clone() " 有什么区别

What is the difference in "directly assigning the class object to another object of same class" and "using clone() "

我是 Java 编码新手。我对获取对象的副本有疑问。

我试图将 obj 分配给另一个相同 Class 的对象,并且成功了。我通过访问两个对象中 class 的项目来确认它,它们是相同的。那clone()有什么用呢?

代码示例:

class student
{
  int id;
  String name;
}

student s1 = new student();
student s2= new student();
s1.id =10;
s2=s1;

所以 s2 也有与 s1 相同的副本 - 是吗?那么克隆需要什么?

分配对象只不过是指向已创建对象的引用。但是克隆是整个对象的精确副本。 尝试使用新引用更改值,实际对象属性将被更改,但在您克隆中,只有新创建的对象将被更改,实际对象保持不变。

clone() 方法节省了创建对象的精确副本的额外处理任务。如果我们使用 new 关键字执行它,将需要执行大量处理,这就是我们使用对象克隆的原因。

当您将一个对象分配给另一个对象时,它只是引用相同的位置。即两个对象具有相同的内存位置。如果您检查,这两个对象将具有相同的属性值。

但是,它暴露了一个问题。每当您更新第一个对象时,第二个对象的值也会更新。

示例:

public class Student implements Cloneable{

int id;
String name;

public Student(int id, String name) {
    this.id = id;
    this.name = name;
}

public static void main(String[] args) throws CloneNotSupportedException {
    Student s1 = new Student(10, "A");
    Student s2 = s1;                        //simply assigning the s1 object's reference to s2
    Student s3= (Student)s1.clone();        //assigning s1 object's clone to s3

    System.out.printf("Before updation::s1.id->%d, s1.name->%s\n",s1.id, s1.name);
    System.out.printf("Before updation::s2.id->%d, s2.name->%s\n",s2.id, s2.name);
    System.out.printf("Before updation::s3.id->%d, s3.name->%s\n",s3.id, s3.name);

    s1.id = 20;
    s1.name= "Z";

    System.out.printf("After updation::s1.id-%d, s1.name->%s\n",s1.id, s1.name);
    System.out.printf("After updation::s2.id-%d, s2.name->%s\n",s2.id, s2.name);
    System.out.printf("After updation::s3.id-%d, s3.name->%s\n",s3.id, s3.name);
}
}

输出:
Before updation::s1.id->10, s1.name->A
Before updation::s2.id->10, s2.name->A
Before updation::s3.id->10, s3.name->A
After updation::s1.id-20, s1.name->Z
After updation::s2.id-20, s2.name->Z
After updation::s3.id-10, s3.name->A

通常是对象的克隆方法,创建相同的新实例 class 并将所有字段复制到新实例和 returns 它。这不过是浅拷贝。 Object class 提供了一个克隆方法,并提供了对浅拷贝的支持。它 returns ‘Object’ 作为类型,你需要明确地转换回你的原始对象。

因此,当您更改原始对象的值时,克隆对象的值保持不变。

由于对象 class 具有克隆方法(受保护),因此您不能在所有 class 中使用它。您要克隆的 class 应该实现克隆方法并覆盖它。它应该为复制提供自己的含义,或者至少应该调用 super.clone()。您还必须实现 Cloneable 标记接口,否则您将获得 CloneNotSupportedException。