区别:复制一个对象时,有两种情况:1.浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。 简而言之,需要复用现有对象的基本类型的成员变量数据时,浅拷贝即可。
2.复制整个对象(复制前后两个对象完全一样)。 深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。深拷贝相比于浅拷贝速度较慢并且花销较大。
实体类
import java.io.*; public class Student3 implements Serializable,Cloneable{ private static final long serialVersionUID = 3462139480068147262L; private Integer age; private String name; public Student3(Integer age, String name) { this.age = age; this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
测试类:举例java两种情况下拷贝具体例子(1.java clone方法及java序列化对象)
java里面还有一种实现深拷贝的方法,就是运用对象的序列化机制。
序列化机制有一种用法:提供了一种克隆对象的简便途径,只要对应的类是可序列化的就可以,做法是:直接将对象序列化到输出流中,然后将其读回,这样产生的新的对象是对现有对象的一个深拷贝。在此过程中,我们不必将对象写到文件中,因为可以用ByteArrayOutputStream将数据保存到字节数组中。
public static void main(String[] args) throws CloneNotSupportedException { File file = new File("D:/test.txt"); Student3 stu = new Student3(18, "xiaoxian"); System.out.println("clone方法是浅拷贝"); Student3 clone = (Student3)stu.clone(); System.out.println("clone == stu的结果:"+ (clone==stu)); System.out.println("clone.name == stu.name的结果:"+ (clone.name==stu.name)); System.out.println("将对象序列化是深拷贝"); //将对象序列化到IO流中 try { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); objectOutputStream.writeObject(stu); objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } //将对象从IO流中反序列化出来 try { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file)); Student3 student3 = (Student3) objectInputStream.readObject(); System.out.println("student3 == stu的结果:"+(stu == student3)); System.out.println("student3.name == stu.name的结果:"+(stu.name == student3.name)); } catch (Exception e) { e.printStackTrace(); } } }
上面我们仅考虑属性是常变量,如果属性也是一个对象的话,浅拷贝仅复制一个对象,属性成员对象被该对象和复制对象共享。深拷贝会再多复制一个属性成员的对象。
实体
class Student implements Cloneable { private String name; private int age; private Teacher teacher; //一个属性对象,可观察一下深浅拷贝后这个对象是一个还是多了一个 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; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } public Object clone() throws CloneNotSupportedException { Object object = super.clone(); return object; } }