一、使用clone复制
public class CloneTest {
public static void main(String[] args) {
Person p1 = new Person("张居正",10,new StringBuffer("男"),new Address("北京",3008));
System.out.println("被clone之前的p1=="+p1);
Person p2 = (Person) p1.clone();
System.out.println("克隆产生的p2=="+p2);
System.out.println("***********************************");
p2.name = "戚继光";
p2.age = 12;
p2.sex.append("猛男");
p2.address.city = "天津";
p2.address.number = 9000;
System.out.println("改变p2的属性之后:");
System.out.println("p1=="+p1);
System.out.println("p2=="+p2);
System.out.println("p1和p2的属性都不相等,证明确实实现了深层复制!");
}
}
//Address类型属于能够直接调用clone方法实现深层复制的其他类型
class Address implements Cloneable{
public String city;
public int number;
public Address(String city,int number){
this.city = city;
this.number = number;
}
@Override
public Object clone()
throws CloneNotSupportedException{
return super.clone();
}
@Override
public String toString(){
return "city="+city+";number="+number;
}
}
//用于序列化的类
//第一,必须实现java.lang.Cloneable接口
class Person implements Cloneable{
//第二,所有属性必须是基本数据类型、String、StringBuffer类型,或者能够直接调用clone方法实现深度复制的其他类型
//注意:StringBuffer类型不能够直接调用clone方法实现直接复制
public String name;
public int age;
public StringBuffer sex;
public Address address;
public Person(
String name,int age,
StringBuffer sex,
Address address){
this.name = name;
this.age = age;
this.sex = sex;
this.address = address;
}
//第三,必须重写clone方法
@Override
public Object clone(){
Person p = null;
try {
//第四,对于基本数据类型和String类型,在调用super.clone()方法时,就已经复制成功了
p = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
//第五,如果属性是StringBuffer类型,则需要使用下面是形式再次给属性赋值
p.sex = new StringBuffer(this.sex.toString());
//第六,如果实行不是基本数据类型、String、StringBuffer类型,则使用一下进行属性的深层复制
try {
p.address = (Address) address.clone();
} catch (CloneNotSupportedException e) {
p.address = null;
e.printStackTrace();
}
return p;
}
@Override
public String toString(){
return "name="+name+";age="+age+";sex="+sex.toString()+";address={"+address+"}";
}
}
运行结果:
被clone之前的p1==name=张居正;age=10;sex=男;address={city=北京;number=3008}
克隆产生的p2==name=张居正;age=10;sex=男;address={city=北京;number=3008}
***********************************
改变p2的属性之后:
p1==name=张居正;age=10;sex=男;address={city=北京;number=3008}
p2==name=戚继光;age=12;sex=男猛男;address={city=天津;number=9000}
p1和p2的属性都不相等,证明确实实现了深层复制!
二、使用序列化复制
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 SerializableTest {
public static void main(String[] args)
throws IOException, ClassNotFoundException {
Person p1 = new Person("张居正",10,new StringBuffer("男"));
System.out.println("序列化之前的p1=="+p1);
byte [] bytes = serializeToByte(p1);
Person p2 = (Person)deserializeToObject(bytes);
System.out.println("反序列化之后的p2=="+p2);
System.out.println("***********************************");
p2.name = "戚继光";
p2.age = 12;
p2.sex.append("猛男");
System.out.println("改变p2的属性之后:");
System.out.println("p1=="+p1);
System.out.println("p2=="+p2);
System.out.println("p1和p2的属性都不相等,证明确实实现了深层复制!");
}
//将Java对象序列化为byte数组
public static byte [] serializeToByte(Object obj)
throws IOException{
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(obj);
return byteOut.toByteArray();
}
//将byte数组反序列化为Java对象
public static Object deserializeToObject(byte [] bytes)
throws IOException, ClassNotFoundException{
ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
ObjectInputStream in =new ObjectInputStream(byteIn);
return in.readObject();
}
}
//用于序列化的类,必须实现java.lang.Serializable接口
class Person implements Serializable{
public String name;
public int age;
public StringBuffer sex;
public Person(String name,int age,StringBuffer sex){
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString(){
return "name="+name+";age="+age+";sex="+sex.toString();
}
}
注意:被序列化的对象的类必须已经实现java.lang.Serializable接口。
运行结果:
序列化之前的p1==name=张居正;age=10;sex=男
反序列化之后的p2==name=张居正;age=10;sex=男
***********************************
改变p2的属性之后:
p1==name=张居正;age=10;sex=男
p2==name=戚继光;age=12;sex=男猛男
p1和p2的属性都不相等,证明确实实现了深层复制!
参考文章:http://www.ibm.com/developerworks/cn/java/l-jpointer/index.html