java的 Object 提供了clone方法提供了,这是个受保护的方法,所以不能直接调用
这是我写的方法
pulbic class Student {
......
public Object clone(){
Student o=null;
try
{
o=(Student)super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
o.p=(Professor)p.clone();
return o;
}
......
}
因为需要实现Cloneable接口还需要重写clone方法所以不喜欢这中方式
利用序列化机制实现深度克隆
public Object deepClone() {
//将对象写到流里
ByteArrayOutoutStream bo=new ByteArrayOutputStream();
ObjectOutputStream oo=new ObjectOutputStream(bo);
oo.writeObject(this);
//从流里读出来
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
return(oi.readObject());
}
因为需要克隆的类都需要实现Serializable接口所以不太喜欢这种方式
利用反射机制实现深度克隆
并不需要实现什么接口或者重写什么方法
只需要写一个工具类调用对应的方法就可以实现深克隆 所以比较喜欢这中方式
在看代码前先来分析一下
首先我们需要复制一个对象
有值类型,引用类型
我们可以直接对值类型进行复制
当遇到一个引用类型怎么办?
没关系我们可以吧他当成一个全新的对象再复制一次
也就是说我们首先要有一个方法来复制对象
下面是实现深克隆的核心方法:
public static Object clone(Object copy) throws InstantiationException, IllegalAccessException{
if( copy == null ){
System.err.println("error:原数据为空...");
return copy;
}
return cloneObject(copy);
}
private static Object cloneObject(Object copy){
if( copy == null || isBaseType(copy) ){
return copy;
}
Class c = copy.getClass();
if(c.isArray()){
return cloneArray(copy);
}
Object newIns = null;
try {
newIns = c.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
return null;
}
cloneFields(copy,newIns);
return newIns;
}
private static void cloneFields(Object copy,Object newIns) {
if(copy == null || newIns == null){
return;
}
Field[] fields = getAllFields(copy);
for (Field f : fields) {
if(Modifier.isStatic( f.getModifiers() ) ){
continue;
}
f.setAccessible(true);
try {
f.set(newIns,cloneObject(f.get(copy)));
} catch (IllegalArgumentException | IllegalAccessException e) {
return;
}
}
}
private static void cloneFinal(Object copy, Object newIns){
// 如果这两个常量的值相等 或者 对象的引用不相等 则终止操作
if( copy == null || newIns == null || copy == newIns || !copy.getClass().equals(newIns.getClass()) ){
return;
}
//newIns = cloneObject(copy);
}
private static Object cloneArray(Object copy){
if( copy == null || !copy.getClass().isArray()){
return copy;
}
int size = Array.getLength(copy);
Object newArray = Array.newInstance(copy.getClass().getComponentType(),size );
for (int i = 0; i < size; i++) {
Array.set(newArray, i,cloneObject(Array.get(copy,i)));
}
return newArray;
}
private static Field[] getAllFields(Object copy){
return copy.getClass().getDeclaredFields();
}
//验证是否是基本类型或者是基本类型的包装类
private static boolean isBaseType(Object o){
Class<?> type = o.getClass();
return type.isPrimitive()
|| type.equals(Byte.class)
|| type.equals(Short.class)
|| type.equals(Integer.class)
|| type.equals(Long.class)
|| type.equals(Float.class)
|| type.equals(Double.class)
|| type.equals(Character.class)
|| type.equals(Boolean.class)
|| type.equals(String.class)
? true: false;
}