转自:http://ncs123.iteye.com/blog/1775631
一.Cloneable 的用途
Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。
二.克隆的分类
(1)浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。
(2)深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。
三.克隆的举例
要让一个对象进行克隆,其实就是两个步骤:
1. 让该类实现java.lang.Cloneable接口;
2. 重写(override)Object类的clone()方法。
- public class Wife implements Cloneable {
- private int id;
- private String name;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Wife(int id,String name) {
- this.id = id;
- this.name = name;
- }
- @Override
- public int hashCode() {//myeclipse自动生成的
- final int prime = 31;
- int result = 1;
- result = prime * result + id;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- return result;
- }
- @Override
- public boolean equals(Object obj) {//myeclipse自动生成的
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Wife other = (Wife) obj;
- if (id != other.id)
- return false;
- if (name == null) {
- if (other.name != null)
- return false;
- } else if (!name.equals(other.name))
- return false;
- return true;
- }
- @Override
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- /**
- * @param args
- * @throws CloneNotSupportedException
- */
- public static void main(String[] args) throws CloneNotSupportedException {
- Wife wife = new Wife(1,"wang");
- Wife wife2 = null;
- wife2 = (Wife) wife.clone();
- System.out.println("class same="+(wife.getClass()==wife2.getClass()));//true
- System.out.println("object same="+(wife==wife2));//false
- System.out.println("object equals="+(wife.equals(wife2)));//true
- }
- }
四.浅克隆的举例
- public class Husband implements Cloneable {
- private int id;
- private Wife wife;
- public Wife getWife() {
- return wife;
- }
- public void setWife(Wife wife) {
- this.wife = wife;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public Husband(int id) {
- this.id = id;
- }
- @Override
- public int hashCode() {//myeclipse自动生成的
- final int prime = 31;
- int result = 1;
- result = prime * result + id;
- return result;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- @Override
- public boolean equals(Object obj) {//myeclipse自动生成的
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Husband other = (Husband) obj;
- if (id != other.id)
- return false;
- return true;
- }
- /**
- * @param args
- * @throws CloneNotSupportedException
- */
- public static void main(String[] args) throws CloneNotSupportedException {
- Wife wife = new Wife(1,"jin");
- Husband husband = new Husband(1);
- Husband husband2 = null;
- husband.setWife(wife);
- husband2 = (Husband) husband.clone();
- System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true
- System.out.println("husband object same="+(husband==husband2));//false
- System.out.println("husband object equals="+(husband.equals(husband)));//true
- System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true
- System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//true
- System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true
- }
- }
五.深克隆的举例
如果要深克隆,需要重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法;注意如下代码的clone()方法
- public class Husband implements Cloneable {
- private int id;
- private Wife wife;
- public Wife getWife() {
- return wife;
- }
- public void setWife(Wife wife) {
- this.wife = wife;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public Husband(int id) {
- this.id = id;
- }
- @Override
- public int hashCode() {//myeclipse自动生成的
- final int prime = 31;
- int result = 1;
- result = prime * result + id;
- return result;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Husband husband = (Husband) super.clone();
- husband.wife = (Wife) husband.getWife().clone();
- return husband;
- }
- @Override
- public boolean equals(Object obj) {//myeclipse自动生成的
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Husband other = (Husband) obj;
- if (id != other.id)
- return false;
- return true;
- }
- /**
- * @param args
- * @throws CloneNotSupportedException
- */
- public static void main(String[] args) throws CloneNotSupportedException {
- Wife wife = new Wife(1,"jin");
- Husband husband = new Husband(1);
- Husband husband2 = null;
- husband.setWife(wife);
- husband2 = (Husband) husband.clone();
- System.out.println("husband class same="+(husband.getClass()==husband2.getClass()));//true
- System.out.println("husband object same="+(husband==husband2));//false
- System.out.println("husband object equals="+(husband.equals(husband)));//true
- System.out.println("wife class same="+(husband.getWife().getClass()==husband2.getWife().getClass()));//true
- System.out.println("wife object same="+(husband.getWife()==husband2.getWife()));//false
- System.out.println("wife object equals="+(husband.getWife().equals(husband.getWife())));//true
- }
- }
但是也有不足之处,如果Husband内有N个对象属性,突然改变了类的结构,还要重新修改clone()方法。解决办法:可以使用Serializable运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
参考java创建对象的第四种方法:
http://ncs123.iteye.com/blog/1775661
相关推荐
总之,Java的`clone`机制提供了复制对象的能力,通过实现`Cloneable`接口和覆盖`clone`方法,我们可以创建对象的副本,同时保证原对象不受影响。根据需求的不同,可以选择浅克隆或深克隆来处理对象及其引用的复杂性...
总结来说,Java中的`clone`方法是一种快速创建对象副本的手段,但它需要谨慎使用,特别是在处理包含复杂数据结构的对象时。理解其工作原理,以及何时和如何正确地使用`clone`,对于提升代码质量和效率至关重要。在...
`clone()`的使用通常涉及到深度复制和浅复制的概念,这两者在数据结构和内存管理中扮演着关键角色。 首先,让我们理解`clone()`的基本用法。`clone()`方法创建并返回一个当前对象的副本,新创建的对象与原对象具有...
它属于`Object`类的一部分,但需要显式地在子类中声明并实现`Cloneable`接口才能正常使用。本文将详细介绍`clone`的基本概念、工作原理以及如何实现浅拷贝和深拷贝。 #### 二、预备知识 在深入了解`clone`之前,...
要使用`clone()`方法,一个类需要实现`Cloneable`接口。这个接口没有定义任何方法,但它的存在表明这个类允许被克隆。如果一个类没有实现`Cloneable`接口,然后尝试调用`clone()`,系统会抛出`...
在Java编程语言中,`Cloneable`接口和`clone()`方法是两个重要的概念,它们用于对象复制。在本文中,我们将深入探讨Java中的浅克隆(shallow clone)和深克隆(deep clone),并结合测试代码进行分析。 首先,让...
在实际编程中,除了`clone()`方法,还可以考虑使用`Serializable`接口结合`ObjectInputStream`和`ObjectOutputStream`实现序列化和反序列化来创建对象的深拷贝。这种方法虽然相对复杂,但对于复杂对象结构的完全复制...
- 实现`Cloneable`接口是调用`clone()`的前提,否则会抛异常。 - 重写`clone()`方法时,需要处理非基本类型的成员变量,确保它们也能够被正确地复制。 总的来说,Java中的克隆机制提供了复制对象的能力,这在很多...
总结一下,Java中的`clone`方法是实现对象复制的一种方式,涉及到浅拷贝和深拷贝的概念。理解并正确使用`clone`对于编写可维护、可扩展的代码至关重要。在实际应用中,根据需求选择合适的复制策略,并注意处理可能...
本资料"Java中clone方法共6页.pdf.zip"可能包含了关于如何理解和使用`clone()`方法的详细解释,以及它在实际开发中的应用示例。 `clone()`方法的主要用途是创建一个现有对象的副本,这个副本与原始对象具有相同的...
实现深度克隆可以采用实现Cloneable接口并重写clone(),或者利用序列化和反序列化技术,具体选择取决于应用场景和性能需求。在实际项目中,应根据具体情况权衡效率和安全性,合理选择克隆策略。
本实验主要讲解了Java中的抽象类和接口的概念和使用方法,并且深入探讨了 Cloneable 接口和 clone 方法在对象内容复制中的应用。 一、抽象类的概念和使用方法 在 Java 中,抽象类是一个不能被实例化的类,它提供了...
深拷贝可以使用多种方法来实现,例如使用序列化和反序列化、使用复制构造函数、使用 clone() 方法等。 例如,我们可以使用下面的代码来实现深拷贝: ```java public class Student implements Cloneable { ...
标题中的"clone type"指的是在编程中的一种复制对象的方式,特别是与Java语言中的`clone()`方法...不过,根据标题和描述,我们可以推断出博客文章可能涵盖了如何在Java编程中正确使用和理解`clone type`的各个方面。
理解对象复制和引用传递的概念对于避免意外的数据修改至关重要,而正确地使用`clone()`方法可以有效地实现这一目标。在实际开发中,我们还需要考虑深复制和浅复制的区别,以及如何根据需求定制`clone()`方法以满足...
总结来说,Java的`clone()`方法用于创建一个现有对象的副本。实现深复制时,需要确保所有引用的对象都进行复制,防止原始对象和副本之间的共享状态。通过自定义`clone()`方法并适当处理类的成员变量,我们可以有效地...
在Java中,实现深复制通常需要通过实现`Cloneable`接口并重写`clone()`方法来完成。`Object`类中的`clone()`方法默认是受保护的,因此我们需要显式地使其可访问,并在子类中覆盖它。在实现`Cloneable`接口后,我们...
在 Java 语言中,有两种方式可以创建对象:使用 new 操作符和使用 clone() 方法。new 操作符的本意是分配内存,程序执行到 new 操作符时,首先需要看 new 操作符后面的类型,因为知道了类型,才能知道要分配多大的...
Java中的对象克隆可以通过实现`Cloneable`接口并覆盖`clone()`方法来完成。对象的克隆分为浅拷贝和深拷贝两种形式。 **1. 浅拷贝** 浅拷贝是指创建一个新的对象,然后将原对象的所有非引用类型的成员变量复制到新...