1. 程式人生 > >反射實現java深度克隆

反射實現java深度克隆

span i++ anti ear access over component [] newobject

、克隆

有時想得到對象的一個復制品,該復制品的實體是原對象實體的克隆。復制品實體的變化不會引起原對象實體發生變化,這樣的復制品稱為原對象實體的克隆對象或簡稱克隆。

1、淺復制(淺克隆)

概念:被復制對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用仍然指向原來的對象。換言之,淺復制僅僅復制所考慮的對象,而不復制它所引用的對象。

方法:類implements Cloneable,然後重寫clone()方法,在clone()方法中調用super.clone()即可,沒有其他操作了

2、深復制(深克隆)

概念:被復制對象的所有變量都含有與原來的對象相同的值,除去那些引用其他對象的變量。那些引用其他對象的變量將指向被復制過的新對象,而不再是原有的那些被引用的對象。換言之,深復制把要復制的對象所引用的對象都復制了一遍。

、克隆的實現

1、通過java的序列化實現克隆,即先對原對象進行序列化,然後再反序列化得到目標對象。

2. 通過反射進行,通過反射,獲取對象的內部數據域,然後將數據依次復制,不多說,先上代碼

package Reflection;

import java.lang.reflect.Array;

import java.lang.reflect.Field;

import java.lang.reflect.Modifier;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public class DeepCloneUtil {

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InstantiationException {

Person p = new Person("zhanchi",26);

System.out.println(Person.num);

Person p2 = (Person) cloneObject(p);

System.out.println(p2.getName());

System.out.println(p2.getAge());

System.out.println(p.list == p2.list);

System.out.println(p2.list.get(0) == p2);

System.out.println(p.list.get(0) == p2);

System.out.println(Person.num);

}

private static List<Field> getAllFieads(Object o) {

List<Field> fields = new ArrayList<Field>();

if (null == o)

return fields;

Class<?> type = o.getClass();

do {

for (Field f : type.getDeclaredFields()) {

fields.add(f);

}

type = type.getSuperclass();

} while (null != type);

return fields;

}

public static boolean isSimpleObject(Object o) {

Class<?> type = o.getClass();

if (type.isPrimitive()) { // 基本類型

return true;

}

// 不可更改的變量類型 如 String,Long

if (type.equals(String.class))

return true;

if (type.equals(Long.class))

return true;

if(type.equals(Boolean.class))

return true;

if(type.equals(Short.class))

return true;

if(type.equals(Integer.class))

return true;

if(type.equals(Character.class))

return true;

if(type.equals(Float.class))

return true;

if(type.equals(Double.class))

return true;

if(type.equals(Byte.class))

return true;

return false;

}

public static Object cloneObject(Object o) throws IllegalArgumentException, IllegalAccessException, InstantiationException{

if(null == o)

return null;

// 使用Map保存原對象和副本對象之間的結構,防止被多次引用的對象重復重建

Map<Object,Object> map = new HashMap<Object,Object>();

return cloneObject(o,map);

}

private static Object cloneObject(Object o, Map<Object, Object> map)

throws IllegalArgumentException, IllegalAccessException,

InstantiationException {

if (null == o)

return null;

Object newInstance = null;

newInstance = map.get(o);

if (null != newInstance) {

return newInstance;

}

if(isSimpleObject(o))

return o;

// 數組類型

if(o.getClass().isArray()){

return cloneArray(o,map);

}

Class<?> type = o.getClass();

newInstance = type.newInstance();

map.put(o, newInstance);

cloneFields(o, newInstance, map);

return newInstance;

}

private static Object cloneArray(Object o,Map<Object, Object> map) throws IllegalArgumentException, IllegalAccessException, InstantiationException{

if(null == o)

return null;

if(!o.getClass().isArray()){

return cloneObject(o,map);

}

int len = Array.getLength(o);

Object array = Array.newInstance(o.getClass().getComponentType(), len);

map.put(o, array);

for(int i = 0; i < len; i++){

Array.set(array, i, cloneObject(Array.get(o, i),map));

}

return array;

}

private static void cloneFinalObject(Object object, Object newObject, Map<Object, Object> map)throws IllegalArgumentException, IllegalAccessException, InstantiationException{

if(object == null || newObject == null || object == newObject || !newObject.getClass().equals(newObject.getClass()))

return ;

// 對於final類型的變量

if(null != map.get(newObject)){

return;

}

map.put(newObject, newObject);

cloneFields(object, newObject, map);

return ;

}

private static void cloneFields(Object object, Object newObject,

Map<Object, Object> map) throws SecurityException,

IllegalArgumentException, IllegalAccessException,

InstantiationException {

if(null == object || null == newObject){

return ;

}

List<Field> fields = getAllFieads(object);

for (Field f : fields) {

// 靜態變量過濾掉 或者final的變量

if(Modifier.isStatic(f.getModifiers()))

continue;

// 常量

if(Modifier.isFinal(f.getModifiers())){

cloneFinalObject(f.get(object),f.get(newObject),map);

}else{

f.setAccessible(true);

f.set(newObject, cloneObject(f.get(object), map));

}

}

}

}

class Person{

static int num = 0;

Person p;

final List<Person> list = new ArrayList<Person>();

String [] testString = new String[3];

public Person() {

num ++ ;

}

public Person(String name, int age) {

this.age=age;

this.name=name;

p = this;

testString[2] = name;

list.add(p);

list.add(new Person());

num ++ ;

}

public String getName() {

return name;

}

public int getAge() {

return age;

}

@Override

public String toString(){

return "["+this.name+" "+this.age+"]";

}

private String name;

private int age;

}

反射實現java深度克隆