在实现原型模式时需要拷贝对象,于是……
浅拷贝:只复制一个对象,对象内部存在的指向其他对象数组或者引用则不复制
深拷贝:对象,对象内部的引用均复制
Object类里的clone方法是浅复制
1. 实现Cloneable接口,该接口没有任何方法和字段实现仅供标记使用。不实现会抛出CloneNotSupportedException。
2. 覆盖clone方法,权限设为public,并在方法内调用super.clone()。
public class CloneTest {
public static void main(String[] args) {
Address address=new Address();
Student student = new Student();
student.setAddress(address);
Student student1=student.clone();
System.out.println(student==student1);
System.out.println(student.getAddress()==student1.getAddress());
}
}
public class Address{
private String addr;
}
public class Student implements Cloneable{
private int age;
private String name;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address= address;
}
@Override
publicStudent clone() {
Student stu=null;
try {
stu= (Student) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return stu;
}
}
方法一:
覆盖此对象的clone方法、覆盖此对象内部的引用对象的clone方法,然后在此对象的clone方法内调用对象内部的引用对象的clone方法,并set进自己的字段里。
此项不写,参考java.util.Date 的深复制clone
public Object clone() {
Date d = null;
try {
d = (Date)super.clone();
if (cdate!= null) {
d.cdate = (BaseCalendar.Date)cdate.clone();
}
} catch (CloneNotSupportedException e) {}// Won't happen
returnd;
}
方法二:
使用Serializable接口
此对象以及所有需要复制的此对象内部所引用的对象都要实现Serializable接口,该接口没有任何方法实现同样仅供标记使用()
最好加上public static final long serialVersionUID=4545154351L;
只需覆盖此对象的clone方法,权限设为public,内部引用对象不需要覆盖
public class CloneTest {
public static void main(String[] args) {
Address address=new Address();
Student student = new Student();
student.setAddress(address);
Student student1=student.clone();
System.out.println(student.getAddress()==student1.getAddress());
}
}
import java.io.Serializable;
public class Address implements Serializable{
public static final long serialVersionUID=4545154351L;
private String addr;
}
import java.io.*;
public class Student implements Serializable{
public static final long serialVersionUID=45451511351L;
private int age;
private String name;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address= address;
}
@Override
publicStudent clone() {
Student stu=null;
try {
ByteArrayOutputStream byteArrayOutputStream=newByteArrayOutputStream();
ObjectOutputStream objectOutputStream=newObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
ByteArrayInputStream bis=newByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = newObjectInputStream(bis);
stu= (Student) objectInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return stu;
}
}
System.arraycopy() 浅拷贝
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
参数:
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
例如: 自我复制 删除threads[i]元素
System.arraycopy(threads, i +1, threads, i, --nthreads- i);
Arrays.copyOf和System.arraycopy的区别?大的区别是没有的,因为Arrays.copyOf内部调用了System.arraycopy
详细用法见
http://blog.csdn.net/csdn9988680/article/details/78160094