对基本类型的属性会进行值传递,当修改其中一个对象中的属性时,不会影响另一个对象中的属性
对引用数据的属性,比如数组或某类对象,会进行引用传递,及两个对象中的属性指向同一个实例对象,修改对象会相互影响。
深拷贝就是对引用类型的数据,也进行拷贝,开辟新的内存空间,两个bean之间相互修改自己的属性不产生影响。
开源工具类- apache的BeanUtils 原理-反射
- apache的PropertyUtils 原理-反射
- spring的BeanUtils 原理-反射
- cglib的BeanCopier 原理-动态代理,性能很高,是反射的几十倍或数百倍
BeanCopiers使用说明 注意事项说明:反射的性能很差,有人做过这几种拷贝工具的性能测试,发现通过反射实现的功能性能很差,不建议在生产环境使用
BeanCopier只有在属性名称和类型都相同的情况下才会进行copy。
工具类用例1(使用同步锁)
public class BeanCopierUtils {
private static Map beanCopierCacheMap = new HashMap<>();
public static void copyProperties(Object source, Object target) {
String cacheKey = source.getClass().toString() + target.getClass().toString();
BeanCopier beanCopier = null;
// 为了线程安全使用双重锁机制
if (!beanCopierCacheMap.containsKey(cacheKey)) {
synchronized (BeanCopierUtils.class) {
if (!beanCopierCacheMap.containsKey(cacheKey)) {
// 进入到这里会创建一个BeanCopier实例并且放在缓存map中
beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopierCacheMap.put(cacheKey, beanCopier);
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
}
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
beanCopier.copy(source, target, null);
}
}
工具类用例1(使用jdk8的concurrentHashMap)
public class BeanCopierUtils {
private static final Map BEAN_COPIER_MAP = new ConcurrentHashMap<>();
public static void copyProperties(Object source, Object target) {
String cacheKey = source.getClass().toString() + target.getClass().toString();
// 查看concurrentHashMap的实现方法介绍可以得知该方法为原子方法,保证了线程安全
BeanCopier beanCopier = BEAN_COPIER_MAP.computeIfAbsent(cacheKey, k -> BeanCopier.create(source.getClass(), target.getClass(), false));
beanCopier.copy(source, target, null);
}
}



