在java中对象的拷贝分为两种:
一种是:浅拷贝(实现Cloneable)
一种是:深拷贝(使用数据流的序列化与反序列化)
浅拷贝的缺点:
1、 基本类型
如果变量是基本很类型,则拷贝其值,比如int、float等。
2、 对象
如果变量是一个实例对象,则拷贝其地址引用,也就是说此时新对象与原来对象是公用该实例变量。
3、 String字符串
若变量为String字符串,则拷贝其地址引用。但是在修改时,它会从字符串池中重新生成一个新的字符串,原有对象保持不变。
如果变量是基本很类型,则拷贝其值,比如int、float等。
2、 对象
如果变量是一个实例对象,则拷贝其地址引用,也就是说此时新对象与原来对象是公用该实例变量。
3、 String字符串
若变量为String字符串,则拷贝其地址引用。但是在修改时,它会从字符串池中重新生成一个新的字符串,原有对象保持不变。
1:浅拷贝代码:
class Person implements Cloneable {
/** 姓名 **/
private String name;
/** 电子邮件 **/
private Email email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Email getEmail() {
return email;
}
public void setEmail(Email email) {
this.email = email;
}
public Person(String name, Email email) {
this.name = name;
this.email = email;
}
public Person(String name) {
this.name = name;
}
protected Person clone() {
Person person = null;
try {
person = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return person;
}
}
class Email {
private String message = "";
public String content = "";
public Email() {
}
public Email(String message, String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
public class TestClone {
public static void main(String[] args) {
// 写封邮件
Email email = new Email("请参加会议", "请与今天12:30到二会议室参加会议...");
Person person1 = new Person("张三", email);
Person person2 = person1.clone();
person2.setName("李四");
Person person3 = person1.clone();
person3.setName("王五");
person1.getEmail().setContent("请与今天12:00到二会议室参加会议...");
// person1.setEmail(new Email("", "请与今天12:00到二会议室参加会议..."));//须要新建对象才可能修改不同的
System.out.println(person1.getName() + "的邮件内容是:"
+ person1.getEmail().getContent());
System.out.println(person2.getName() + "的邮件内容是:"
+ person2.getEmail().getContent());
System.out.println(person3.getName() + "的邮件内容是:"
+ person3.getEmail().getContent());
}
}
修改clone方法其现对象分离(其实就是新建了一个对象)
protected Person clone() {
Person person = null;
try {
person = (Person) super.clone();
person.setEmail(new Email("",person.getEmail().getContent()));
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return person;
}
2:深拷贝(被拷贝对象须要实现 Serializable接口)
拷贝对象的工具类
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class CloneUtils {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj){
T cloneObj = null;
try {
//写入字节流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream obs = new ObjectOutputStream(out);
obs.writeObject(obj);
obs.close();
//分配内存,写入原始对象,生成新对象
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(ios);
//返回生成的新对象
cloneObj = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}
其它类
import java.io.Serializable;
class Person implements Serializable {
private static final long serialVersionUID = 3623459427337616520L;
/** 姓名 **/
private String name;
/** 电子邮件 **/
private Email email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Email getEmail() {
return email;
}
public void setEmail(Email email) {
this.email = email;
}
public Person(String name, Email email) {
this.name = name;
this.email = email;
}
public Person(String name) {
this.name = name;
}
}
class Email implements Serializable{
private static final long serialVersionUID = 2913307304989215405L;
private String message = "";
public String content = "";
public Email() {
}
public Email(String message, String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
public class TestClone {
public static void main(String[] args) {
//写封邮件
Email email = new Email("请参加会议","请与今天12:30到二会议室参加会议...");
Person person1 = new Person("张三",email);
Person person2 = CloneUtils.clone(person1);
person2.setName("李四");
Person person3 = CloneUtils.clone(person1);
person3.setName("王五");
person1.getEmail().setContent("请与今天12:00到二会议室参加会议...");
System.out.println(person1.getName() + "的邮件内容是:" + person1.getEmail().getContent());
System.out.println(person2.getName() + "的邮件内容是:" + person2.getEmail().getContent());
System.out.println(person3.getName() + "的邮件内容是:" + person3.getEmail().getContent());
}
}
参考:http://blog.csdn.net/chenssy/article/details/12952063