package com.n_app.util;  
  
import java.lang.reflect.Constructor;  
import java.lang.reflect.Field;  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Modifier;  
import java.util.Arrays;  
import java.util.Collection;  
import java.util.HashSet;  
import java.util.Map;  
import java.util.Set;  
  
/** 
 * 克隆工具类 
 * @author lujijiang@gmail.com 
 * 
 */  
public class Clone {  
    /** 
     * 无需进行复制的特殊类型数组 
     */  
    static Class[] needlessCloneClasses = new Class[]{String.class,Boolean.class,Character.class,Byte.class,Short.class,  
        Integer.class,Long.class,Float.class,Double.class,Void.class,Object.class,Class.class  
    };  
    /** 
     * 判断该类型对象是否无需复制 
     * @param c 指定类型 
     * @return 如果不需要复制则返回真,否则返回假 
     */  
    private static boolean isNeedlessClone(Class c){  
        if(c.isPrimitive()){//基本类型  
            return true;  
        }  
        for(Class tmp:needlessCloneClasses){//是否在无需复制类型数组里  
            if(c.equals(tmp)){  
                return true;  
            }  
        }  
        return false;  
    }  
      
    /** 
     * 尝试创建新对象 
     * @param c 原始对象 
     * @return 新的对象 
     * @throws IllegalAccessException 
     */  
    private static Object createObject(Object value) throws IllegalAccessException{  
            try {  
                return value.getClass().newInstance();  
            } catch (InstantiationException e) {  
                return null;  
            } catch (IllegalAccessException e) {  
                throw e;  
            }  
    }  
      
    /** 
     * 复制对象数据 
     * @param value 原始对象 
     * @param level 复制深度。小于0为无限深度,即将深入到最基本类型和Object类级别的数据复制; 
     * 大于0则按照其值复制到指定深度的数据,等于0则直接返回对象本身而不进行任何复制行为。 
     * @return 返回复制后的对象 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @throws InvocationTargetException 
     * @throws NoSuchMethodException 
     */  
    public static Object clone(Object value,int level) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException{  
        if(value==null){  
            return null;  
        }  
        if(level==0){  
            return value;  
        }  
        Class c = value.getClass();  
        if(isNeedlessClone(c)){  
            return value;  
        }  
        level--;  
        if(value instanceof Collection){//复制新的集合  
            Collection tmp = (Collection)c.newInstance();  
            for(Object v:(Collection)value){  
                tmp.add(clone(v,level));//深度复制  
            }  
            value = tmp;  
        }  
        else if(c.isArray()){//复制新的Array  
            //首先判断是否为基本数据类型  
            if(c.equals(int[].class)){  
                int[] old = (int[])value;  
                value = (int[])Arrays.copyOf(old, old.length);  
            }  
            else if(c.equals(short[].class)){  
                short[] old = (short[])value;  
                value = (short[])Arrays.copyOf(old, old.length);  
            }  
            else if(c.equals(char[].class)){  
                char[] old = (char[])value;  
                value = (char[])Arrays.copyOf(old, old.length);  
            }  
            else if(c.equals(float[].class)){  
                float[] old = (float[])value;  
                value = (float[])Arrays.copyOf(old, old.length);  
            }  
            else if(c.equals(double[].class)){  
                double[] old = (double[])value;  
                value = (double[])Arrays.copyOf(old, old.length);  
            }  
            else if(c.equals(long[].class)){  
                long[] old = (long[])value;  
                value = (long[])Arrays.copyOf(old, old.length);  
            }  
            else if(c.equals(boolean[].class)){  
                boolean[] old = (boolean[])value;  
                value = (boolean[])Arrays.copyOf(old, old.length);  
            }  
            else if(c.equals(byte[].class)){  
                byte[] old = (byte[])value;  
                value = (byte[])Arrays.copyOf(old, old.length);  
            }  
            else {  
                Object[] old = (Object[])value;  
                Object[] tmp = (Object[])Arrays.copyOf(old, old.length, old.getClass());  
                for(int i = 0;i<old.length;i++){  
                    tmp[i] = clone(old[i],level);  
                }  
                value = tmp;  
            }  
        }  
        else if(value instanceof Map){//复制新的MAP  
            Map tmp = (Map)c.newInstance();  
            Map org = (Map)value;  
            for(Object key:org.keySet()){  
                tmp.put(key, clone(org.get(key),level));//深度复制  
            }  
            value = tmp;  
        }  
        else {  
            Object tmp = createObject(value);  
            if(tmp==null){//无法创建新实例则返回对象本身,没有克隆  
                return value;  
            }  
            Set<Field> fields = new HashSet<Field>();  
            while(c!=null&&!c.equals(Object.class)){  
                fields.addAll(Arrays.asList(c.getDeclaredFields()));  
                c = c.getSuperclass();  
            }  
            for(Field field:fields){  
                if(!Modifier.isFinal(field.getModifiers())){//仅复制非final字段  
                    field.setAccessible(true);  
                    field.set(tmp, clone(field.get(value),level));//深度复制  
                }  
            }  
            value = tmp;  
        }  
        return value;  
    }  
      
    /** 
     * 浅表复制对象 
     * @param value 原始对象 
     * @return 复制后的对象,只复制一层 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @throws InvocationTargetException 
     * @throws NoSuchMethodException 
     */  
    public static Object clone(Object value) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException{  
        return clone(value,1);  
    }  
      
    /** 
     * 深度复制对象 
     * @param value 原始对象 
     * @return 复制后的对象 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @throws InvocationTargetException 
     * @throws NoSuchMethodException 
     */  
    public static Object deepClone(Object value) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException{  
        return clone(value,-1);  
    }  
}
最近下载更多
                
                ideaCode     LV4
                2021年9月29日
            
            
        
                dezend     LV1
                2021年3月14日
            
            
        
                Chenke01     LV1
                2021年3月12日
            
            
        
                wuzhuang01001     LV1
                2020年11月16日
            
            
        
                wojiaotqm     LV2
                2020年9月10日
            
            
        
                guomami     LV1
                2020年8月13日
            
            
        
                platoo     LV1
                2020年8月7日
            
            
        
                ly993066886     LV3
                2020年6月9日
            
            
        
                asdfqwgqg     LV1
                2020年5月11日
            
            
        
                JmCoder     LV1
                2020年3月9日
            
            
        
最近浏览更多
                
                18784679855     LV8
                2022年3月28日
            
            
        
                ideaCode     LV4
                2021年9月29日
            
            
        
                dezend     LV1
                2021年3月14日
            
            
        
                Chenke01     LV1
                2021年3月12日
            
            
        
                wuzhuang01001     LV1
                2020年11月16日
            
            
        
                wojiaotqm     LV2
                2020年9月10日
            
            
        
                guomami     LV1
                2020年8月13日
            
            
        
                platoo     LV1
                2020年8月7日
            
            
        
                kinggode     LV14
                2020年7月28日
            
            
        
                ly993066886     LV3
                2020年6月9日
            
            
        
    
    