Object.clone()方法可以绕过对象构造函数,快速复制一个对象实例。由于不需要调用对象构造函数,因此,clone()方法不会受到构造函数性能的影响,可以快速生成一个实例。
protected native Object clone() throws CloneNotSupportedException解释:
浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。也就是说,对于对象中的field,不管他是基本类型变量还是引用类型的变量,都直接赋值过去,基本类型变量就是把值拷贝过去,引用类型变量就把引用(即地址)拷贝过去。
深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
浅拷贝图例:
深拷贝图例:
public class LearnClone { public static void main(String[] args) throws Exception { Apple apple=new Apple(); apple.id=1; apple.color="red"; List<String> list=new ArrayList<String>(); list.add("hello"); apple.list=list; Apple apple2=apple.clone(); //可以看出,两个对象的地址不同 System.out.println(apple==apple2);//输出false apple2.id=2; apple2.list.add("world"); //可以看出源对象和拷贝对象的基本类型变量相互独立。然后,引用类型的变量指向了一个地址 System.out.println(apple); System.out.println(apple2); //输出:id:1,color:red,list:[hello, world] //输出:id:2,color:red,list:[hello, world] } } class Apple implements Cloneable{ int id; String color; List<String> list; @Override public Apple clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return (Apple)super.clone(); } @Override public String toString() { // TODO Auto-generated method stub return "id:"+id+",color:"+color+",list:"+list; } }
只需要改写一下浅拷贝的clone函数
class Apple implements Cloneable{ int id; String color; List<String> list; @Override public Apple clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Apple apple=(Apple)super.clone(); List<String> list2=new ArrayList<String>(); for (String str : list) { list2.add(str); } apple.list=list2; return apple; } @Override public String toString() { // TODO Auto-generated method stub return "id:"+id+",color:"+color+",list:"+list; } }
public class LearnDeepCopy { public static void main(String[] args) throws Exception{ List<String> list=new ArrayList<String>(); list.add("hello"); Orange orange=new Orange(1, "yellow",list); Orange copy=null; //将对象写到流里面 ByteArrayOutputStream byteArrayOutput=new ByteArrayOutputStream(); ObjectOutputStream objectOutput=new ObjectOutputStream(byteArrayOutput); objectOutput.writeObject(orange); objectOutput.flush(); //从流里面在读出对象 ByteArrayInputStream byteArrayInput=new ByteArrayInputStream(byteArrayOutput.toByteArray()); ObjectInputStream objectInput=new ObjectInputStream(byteArrayInput); copy=(Orange)objectInput.readObject(); copy.list.add("world"); //可以发现两个对象的地址不同 System.out.println("orange==copy:"+(copy==orange)); //输出:orange==copy:false System.out.println(orange); //输出:id:1,color:yellow,list:[hello] System.out.println(copy); //输出:id:1,color:yellow,list:[hello, world] } } class Orange implements Serializable { private int id; private String color; List<String> list; public Orange(int id,String color,List<String> list) { // TODO Auto-generated constructor stub this.id=id; this.color=color; this.list=list; } @Override public String toString() { // TODO Auto-generated method stub return "id:"+id+",color:"+color+",list:"+list; } }缺点: