我是Java
编码新手。我对获取一个对象的副本有疑问。
我尝试将obj分配给另一个具有相同Class
的对象,并且它有效。我通过访问两个对象中的类的项目来确认它,它们是相同的。那么clone()
的用途是什么?
代码示例:
class student
{
int id;
String name;
}
student s1 = new student();
student s2= new student();
s1.id =10;
s2=s1;
所以s2
也与s1
的副本相同 - 是吗?那么克隆需要什么呢?
答案 0 :(得分:3)
分配对象只是指向创建对象的引用。但克隆与整个对象完全相同。 尝试使用新引用更改值,实际对象属性将被更改,但在您克隆时,只有新创建的对象才会被更改,实际对象保持不变。
答案 1 :(得分:2)
clone()方法保存额外的处理任务,以创建对象的精确副本。如果我们使用new关键字执行它,则需要执行大量处理才能使用对象克隆。
答案 2 :(得分:1)
将一个对象分配给另一个对象时,它仅引用同一位置。即两个对象具有相同的存储位置。如果选中,则两个对象的属性值都相同。
但是,它暴露了一个问题。每当更新第一个对象时,第二个对象的值也会更新。
示例:
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
通常克隆对象的方法,创建同一个类的新实例,并将所有字段复制到新实例并返回它。这只不过是浅色的副本。 Object类提供克隆方法并为浅拷贝提供支持。它返回'Object'作为类型,您需要显式地转换回原始对象。
因此,当您更改原始对象的值时,克隆对象的值保持不变。
由于Object类具有clone方法(受保护),因此无法在所有类中使用它。要克隆的类应该实现克隆方法并覆盖它。它应该为复制提供它自己的含义,或者至少它应该调用super.clone()。此外,您必须实现Cloneable标记接口,否则您将获得CloneNotSupportedException。