标签:
protected native Object clone() throws CloneNotSupportedException;
通常克隆对象都是通过调用super.clone()方法来获取克隆对象的,所以任何克隆的过程最终都将到达java.lang.Object 的clone()方法。但是在覆写clone()方法时,这个类需要继承Clonable接口,这个接口中没有定义方法,只做为一种标识存在。如果 clone 类没有实现 Cloneable 接口,并调用了 Object 的 clone() 方法(也就是调用了 super.Clone() 方法),那么Object 的 clone() 方法就会抛出 CloneNotSupportedException 异常。
从上述的第二和第三点可以看出,克隆完全是拷贝一个独立的副本到内存中。但是由于克隆方法可以覆写,所以并不能保证克隆出来的对象能够达到(2)和(3)要求的标准,所以他们不是克隆方法所必须要求的。
只对对象本身进行拷贝,而不对对象包含的引用进行拷贝。
package com.xqq.浅拷贝;
public class Professor implements Cloneable {
private int age;
private String name;
public Professor(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() {
Professor professor = null;
try {
professor = (Professor) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return professor;
}
@Override
public String toString() {
return "Professor name:" + name + " age:" + age;
}
}
package com.xqq.浅拷贝;
public class Student implements Cloneable {
private String name;
private int age;
private Professor professor;// 浅拷贝完之后,所指对象仍为同一个
public Student(String name, int age, Professor professor) {
this.name = name;
this.age = age;
this.professor = professor;
}
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 Professor getProfessor() {
return professor;
}
public void setProfessor(Professor professor) {
this.professor = professor;
}
@Override
protected Object clone() {
Student student = null;
try {
student = (Student) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return student;
}
@Override
public String toString() {
return "Student name: " + name + " age:" + age + " professor: "
+ professor;
}
}
package com.xqq.浅拷贝;
public class TestShallowCopy {
public static void main(String[] args) {
String name = "Tom";
int age = 20;
Professor professor = new Professor(30, "Json");
Student student1 = new Student(name, age, professor);
Student student2 = (Student)student1.clone();
System.out.println("1" + student1);
System.out.println("Copy" + student2);
System.out.println("修改了学生1的教授名-------");
professor.setName("Change");
System.out.println(student1);
System.out.println(student2);
}
}
运行结果:
1Student name: Tom age:20 professor: Professor name:Json age:30
CopyStudent name: Tom age:20 professor: Professor name:Json age:30
修改了学生1的教授名-------
Student name: Tom age:20 professor: Professor name:Change age:30
Student name: Tom age:20 professor: Professor name:Change age:30
可以看出,基本类型可以使用浅克隆,而对于引用类型,由于引用的是内容相同,所以改变shallow1实例对象中的属性就会影响shallow2对象中的属性。
深拷贝与浅拷贝的主要区别在于对复合类型数据的复制,若对象中的某个字段为复合类型数据,在拷贝时,需要对该字段也进行一份拷贝,深拷贝相当于对浅拷贝进行递归。
package com.xqq.深拷贝;
public class Professor implements Cloneable {
private int age;
private String name;
public Professor(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone(){
Professor professor = null;
try {
professor = (Professor)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return professor;
}
@Override
public String toString() {
return "Professor name:" + name + " age:" + age;
}
}
package com.xqq.深拷贝;
public class Student implements Cloneable {
private String name;
private int age;
private Professor professor;// 浅拷贝完之后,所指对象仍为同一个
public Student(String name, int age, Professor professor) {
this.name = name;
this.age = age;
this.professor = professor;
}
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 Professor getProfessor() {
return professor;
}
public void setProfessor(Professor professor) {
this.professor = professor;
}
@Override
protected Object clone() {
Student student = null;
try {
student = (Student) super.clone();// 对自身对象克隆
student.setProfessor((Professor)professor.clone());//还要对该对象内部的引用变量进行克隆
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return student;
}
@Override
public String toString() {
return "Student name: " + name + " age:" + age + " professor: "
+ professor;
}
}
package com.xqq.深拷贝;
public class TestDeepCopy {
public static void main(String[] args) {
String name = "Tom";
int age = 20;
Professor professor = new Professor(30, "Json");
Student student1 = new Student(name, age, professor);
Student student2 = (Student)student1.clone();
System.out.println("1" + student1);
System.out.println("Copy" + student2);
System.out.println("修改了学生1的教授名-------");
professor.setName("Change");
System.out.println(student1);
System.out.println(student2);
}
}
运行结果:
1Student name: Tom age:20 professor: Professor name:Json age:30
CopyStudent name: Tom age:20 professor: Professor name:Json age:30
修改了学生1的教授名-------
Student name: Tom age:20 professor: Professor name:Change age:30
Student name: Tom age:20 professor: Professor name:Json age:30
package com.xqq.深拷贝之串行化;
import java.io.Serializable;
public class Professor implements Serializable {
private static final long serialVersionUID = -5625634096029788266L;
private int age;
private String name;
public Professor(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Professor name:" + name + " age:" + age;
}
}
package com.xqq.深拷贝之串行化;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = -6910385562039120926L;
private String name;
private int age;
private Professor professor;// 浅拷贝完之后,所指对象仍为同一个
public Student(String name, int age, Professor professor) {
this.name = name;
this.age = age;
this.professor = professor;
}
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 Professor getProfessor() {
return professor;
}
public void setProfessor(Professor professor) {
this.professor = professor;
}
public Object deepClone() throws IOException, ClassNotFoundException {
//创建输出流
ByteArrayOutputStream out = new ByteArrayOutputStream();
//输出流对象
ObjectOutputStream oos = new ObjectOutputStream(out);
//将对象写进输出流
oos.writeObject(this);
//创建输入流
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
//从输入流读出读出对象
Student student = (Student) ois.readObject();
return student;
}
@Override
public String toString() {
return "Student name: " + name + " age:" + age + " professor: "
+ professor;
}
}
package com.xqq.深拷贝之串行化;
import java.io.IOException;
public class TestShallowCopy {
public static void main(String[] args) throws ClassNotFoundException, IOException {
String name = "Tom";
int age = 20;
Professor professor = new Professor(30, "Json");
Student student1 = new Student(name, age, professor);
Student student2 = (Student)student1.deepClone();
System.out.println("1" + student1);
System.out.println("Copy" + student2);
System.out.println("修改了学生1的教授名-------");
professor.setName("Change");
System.out.println(student1);
System.out.println(student2);
}
}
运行结果:
1Student name: Tom age:20 professor: Professor name:Json age:30
CopyStudent name: Tom age:20 professor: Professor name:Json age:30
修改了学生1的教授名-------
Student name: Tom age:20 professor: Professor name:Change age:30
Student name: Tom age:20 professor: Professor name:Json age:30
但是串行化却很耗时,在一些框架中,它们往往将对象进行串行化后进行传递,耗时较多。
本文参考:http://www.cnblogs.com/shuaiwhu/archive/2010/12/14/2065088.html
标签:
原文地址:http://blog.csdn.net/chun0801/article/details/51858835