Clone对象

这篇文章来源于《java面试宝典》抱歉忘了引用地址:想发布为引用文章的,但是没有引用地址这个必填项,暂且作为原创吧,毕竟里面的部分文字和代码自己敲的;

1、Clone
在编程中我们会遇到这种情况,目前:有一个对象A已经有许多有效的数值,此时我们需要对象B 和A一致,并且对B的以后的修改不影响A的值,就是A与B是两个独立的值,但是B的初始值是A,clone就是实现这种操作最简单的方法:

就像:copy一份文件夹,一模一样的,对copy版本的操作不影响原版的数据;

2、new 一个对象与Clone的区别

new操作就是分配内存。程序执行到new操作时,首先去看new操作后的类型,确定需要分配多大的内存空间。分配完成内存后,调用构造函数,填充对象的各个域,这是初始化,然后一个对象创建完毕,将引用地址发布到外部就可以使用这个对象;

clone的操作第一步也是分配内存,调用clone方法时,分配的内存与原对象相同,然后再使用原对象的对象中各个域中的数据填充新的对象域,填充完毕后但会被创建的对象,把对象的引用地址发布到外部就可以使用这个对象;

3、clone的对象的使用

public class CloneTest {
  public static void main(String[] args) throws CloneNotSupportedException {
	
	  //-------------------复制引用-----------------
	  Person p1=new Person("zhang", 23);
	  Person p2=p1;
	  System.out.println(p1);
	  System.out.println(p2);
	  /**
	   * result:org.pbccrc.org.pbccrc.Person@15db9742
                org.pbccrc.org.pbccrc.Person@15db9742
                                 复制引用是同一个对象
	   */
	//----------------------Clone---------------------------------  
	  Person p3=new Person("zhang", 23);
	  Person p4=(Person) p3.clone();
	  System.out.println(p3);
	  System.out.println(p4);
	  /**
	   * result:org.pbccrc.org.pbccrc.Person@6d06d69c
                org.pbccrc.org.pbccrc.Person@7852e922
         Clone:是不同的对象       
	   */
  }
}

复制引用
在这里插入图片描述
复制对象
在这里插入图片描述
4、深拷贝与浅拷贝

public class Person implements Cloneable {
	
	private String name;
	   
	private int age;
	
   public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

   public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return (Person)super.clone();
	}
	
}

在clone时由于 age 是基本数据类型,直接将一个 4 字节的整数值拷贝过来就行。但是 name 是 String 类型的, 它只是一个引用, 指向一个真正的 String 对象,那么对它的拷贝有两种方式: 直接将原对象中 的 name 的引用值拷贝给新对象的 name 字段, 或者是根据原 Person 对象中的 name 指向的字符串对象创建一个 新的相同的字符串对象,将这个新字符串对象的引用赋给新拷贝的 Person 对象的 name 字段。

在这里插入图片描述

//----------------------Clone---------------------------------  
	  Person p3=new Person("zhang", 23);
	  Person p4=(Person) p3.clone();
	  System.out.println(p3);
	  System.out.println(p4);
	  /**
	   * result:org.pbccrc.org.pbccrc.Person@6d06d69c
                org.pbccrc.org.pbccrc.Person@7852e922
         Clone:是不同的对象       
	   */
	  
	  //----------------验证是否深浅拷贝----------
	  String result=p3.getName()==p4.getName()?"String类型的 name浅拷贝":"String类型的 name深拷贝";
      System.out.println(result); 
String类型的 name浅拷贝
注:对于对象中的引用类型调用Clone方法,其实是浅拷贝

5、实现深拷贝
实现一个对象的深拷贝需要:
1、需要深拷贝的对象实现Cloneable接口;
2、重写其中的clone方法,调用clone方法时需要将对象中引用类型对象clone一份;
3、对象中的引用类型实现cloneable接口并重写clone方法;

public class CloneTest2 {
  public static void main(String[] args) throws CloneNotSupportedException {
	 Body body=new Body(new Head(new Face()));
	 Body body1 = (Body) body.clone();
	 System.out.println("body == body1 : " + (body == body1) ); 
	 System.out.println("body.head == body1.head : " +  (body.head == body1.head));
	  
 }

 static class Body implements Cloneable{
     
	  private Head head; 
	  public Body(Head head) {
		super();
		this.head = head;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		  Body body= (Body) super.clone();
		  body.head=(Head) head.clone();
		  return body;
	}
  }
  
 static  class Head implements Cloneable{
	    private Face face; 
	    
	    public Head(Face face) {
			super();
			this.face = face;
		}

		@Override
	    protected Object clone() throws CloneNotSupportedException {
	      Head head=(Head) super.clone();
	      head.face=(Face)face.clone();
	    	return head;
	    }
	  
  }
  
 static class Face implements Cloneable{
	   
	   public Face() {
		super();
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		  return super.clone();
	}
	  
  }
}
result:
body == body1 : false
body.head == body1.head : false
发布了15 篇原创文章 · 获赞 7 · 访问量 2852

猜你喜欢

转载自blog.csdn.net/xiaocaodeshengri/article/details/100917755