/* * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jef.tools.reflect; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import jef.accelerator.cglib.beans.BeanCopier; import jef.accelerator.cglib.core.Converter; import jef.common.SimpleMap; /** * 深拷贝工具,基于CG-Lib,可以对任何对象实施Clone.是目前已知的最高效的Java实现 * * @author Administrator * */ public class CloneUtils { private static ConcurrentMap<Class<?>, Cloner> BEAN_CLONERS = new ConcurrentHashMap<Class<?>, Cloner>(32); /** * 常用的克隆策略,预定义好。 */ static { BEAN_CLONERS.put(ArrayList.class, Cloner._ArrayList); BEAN_CLONERS.put(Arrays.asList().getClass(), Cloner._ArrayList); BEAN_CLONERS.put(LinkedList.class, new Cloner._OtherCollection(LinkedList.class)); BEAN_CLONERS.put(HashSet.class, Cloner._HashSet); BEAN_CLONERS.put(TreeSet.class, new Cloner._OtherCollection(TreeSet.class)); BEAN_CLONERS.put(HashMap.class, Cloner._HashMap); BEAN_CLONERS.put(SimpleMap.class, Cloner._HashMap); BEAN_CLONERS.put(ConcurrentHashMap.class, new Cloner._OtherMap(ConcurrentHashMap.class)); BEAN_CLONERS.put(TreeMap.class, new Cloner._OtherMap(TreeMap.class)); BEAN_CLONERS.put(String.class, Cloner.RAW); BEAN_CLONERS.put(Integer.class, Cloner.RAW); BEAN_CLONERS.put(Long.class, Cloner.RAW); BEAN_CLONERS.put(Short.class, Cloner.RAW); BEAN_CLONERS.put(Float.class, Cloner.RAW); BEAN_CLONERS.put(Double.class, Cloner.RAW); BEAN_CLONERS.put(Boolean.class, Cloner.RAW); BEAN_CLONERS.put(Byte.class, Cloner.RAW); BEAN_CLONERS.put(Character.class, Cloner.RAW); BEAN_CLONERS.put(java.util.Date.class, Cloner.DATE); BEAN_CLONERS.put(java.sql.Date.class, Cloner.SQL_DATE); BEAN_CLONERS.put(java.sql.Time.class, Cloner.TIME); BEAN_CLONERS.put(java.sql.Timestamp.class, Cloner.TIMESTAMP); } /** * 注册一个自定义的克隆策略。 * 默认策略能处理大多数的集合、数组、自定义Bean、常见基本类型等克隆。但如果你有特殊的Bean需要克隆,可以注册自定义的策略。 * * @param type * 要注册的克隆类 * @param cloner * 克隆实现。 * @return 如果注册的策略替换了系统已注册的某项的策略,那么返回被替换的策略。 */ public static Cloner register(Class<?> type, Cloner cloner) { return BEAN_CLONERS.put(type, cloner); } /** * 给定一个类型吗,返回该类型的克隆策略。 * * @param clz * @return */ public static Cloner getCloner(Class<?> clz) { Cloner cloner = BEAN_CLONERS.get(clz); if (cloner != null) return cloner; if (isStateLessType(clz)) {// cloner = Cloner.RAW; } else if(clz.isArray()){ cloner = Cloner._Array; } else if (Collection.class.isAssignableFrom(clz)) {// 按未知集合类型处理 cloner = new Cloner._OtherCollection(clz); } else if (Map.class.isAssignableFrom(clz)) {// 按未知Map类型处理 cloner = new Cloner._OtherMap(clz); } else {// 按自定义Bean处理 cloner = new BeanCloner(BeanCopier.create(clz, clz, true)); } BEAN_CLONERS.putIfAbsent(clz, cloner); return cloner; } /** * 深拷贝 (被动式,仅对DeepCloneable接口的类进行深拷贝) * * @param obj * 要拷贝的对象 * @return 拷贝后的对象,那么除非属性继承了{@link DeepCloneable}接口,否则不会深拷贝。 */ public static Object clone(Object obj) { return clone(obj, false); } /** * 带泛型的深拷贝(被动式,仅对DeepCloneable接口的类进行深拷贝) * @param obj * @return */ @SuppressWarnings("unchecked") public static <T> T clone2(T obj) { return (T)clone(obj, false); } /** * 带泛型的深拷贝(主动式,对一切类都尽可能尝试深拷贝) * @param obj * @return */ @SuppressWarnings("unchecked") public static <T> T deepClone(T obj) { return (T)clone(obj, true); } /** * 深拷贝 * * @param obj * 要拷贝的对象 * @param deep * 对象内的属性是否深拷贝。如果为true则尝试递归向下深拷贝。如为false,那么除非属性继承了 * {@link DeepCloneable}接口,否则不会深拷贝。 * @return 拷贝后的对象 */ public static Object clone(Object obj, boolean deep) { return _clone(obj, deep?Integer.MAX_VALUE:1); } static Object _clone(Object bean, int restLevel) { if (bean == null) { return null; } if (restLevel>0 || bean instanceof DeepCloneable) { return getCloner(bean.getClass()).clone(bean, restLevel-1); }else{ return bean; } } static final Converter clone_cvt_dummy = new Converter() { public Object convert(Object pojo, Class fieldType, Object fieldName) { return pojo; } }; static final class CloneConvert implements Converter { private int restLevel; CloneConvert(int restLevel){ this.restLevel=restLevel; } @SuppressWarnings("rawtypes") public Object convert(Object pojo, Class fieldType, Object fieldName) { return _clone(pojo, restLevel); } }; public static boolean isStateLessType(Class<?> cls) { if (cls.isPrimitive()) return true; if (cls.getName().startsWith("java.lang.")) return true; if (cls.getName().startsWith("java.io.")) return true; if (cls.isEnum()) return true; return false; } }