JavaBean深拷贝工具类,可以拷贝所有子类以及List中的范型(反射实现)

2 篇文章 0 订阅

JavaBean深拷贝

作者:N_Xiang
QQ:1164048272
写的比较粗糙,仅满足目前项目,有修改请留言评论,或者加QQ一起讨论

父类拷贝暂时预留,还没有写

1、方法一:快速使用方法->导包

<dependency>
  <groupId>com.lnx10</groupId>
  <artifactId>sr-all</artifactId>
  <version>0.0.1</version>
</dependency>
1.1 导入后直接使用
SrBeanUtils.copy(source,targert)

2、方法二:实现源码工具类

package com.kingint.base.commonxiruan.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author N_Xiang
 * @describe JavaBean工具类
 * @time 2021/11/10 11:21 下午
 */
public class KtBeanUtils {

    private static Map<String,Method> cachMap = new ConcurrentHashMap<>();

    /**
     * 仅仅拷贝本身
     * @param source
     * @param target
     */
    public static void copy(Object source ,Object target){
        toJavaBean(source,target,false);
    }

    /**
     * 仅仅拷贝本身
     * @param source
     * @param target
     * @param type 类型  true拷贝父类 false正常拷贝
     */
    public static void copy(Object source ,Object target,Boolean type){
        toJavaBean(source,target,type);
    }

    /**
     * Bean拷贝
     * @param source 元数据
     * @param target 目标数据
     * @param type 类型  true拷贝父类 false正常拷贝
     */
    private static void toJavaBean(Object source ,Object target,Boolean type){
        //Map<String, String> map = KtAliasPars.ParsAlias(source);
        Class<?> cTarget = target.getClass();
        Class<?> cSource = source.getClass();
        //获得某个类的所有声明的字段
        Field[] fields = cTarget.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            // 获得属性的首字母并转换为大写
            String firstLetter = fieldName.substring(0, 1).toUpperCase().concat(fieldName.substring(1));
            String setMethodName = "set" + firstLetter;
            String getMethodName = "get" + firstLetter;
           // if (map.containsKey(fieldName)){
                //取出某个字段对呀目标数据的字段名
               // String k = map.get(fieldName);
               // String kFirstLetter = k.substring(0,1).toUpperCase().concat(k.substring(1));
               // getMethodName = "get"+kFirstLetter;
//                setMethodName = "set"+kFirstLetter;
                //}

            try {
                //获取源对象的值
                Method cmethod = cachMap.getOrDefault(cSource.getName()+"@"+getMethodName,cSource.getMethod(getMethodName));
                Object cinvoke = cmethod.invoke(source);
                cachMap.put(cSource.getName()+"@"+getMethodName,cmethod);
                if (!isWrapClass(field.getType())){

                    if (field.getType().equals(List.class)){
                        List<Object> o = new ArrayList<>();
                        copyListProperties((List<Object>)cinvoke, o,getT(field));
                        cinvoke = o;
                    }else {
                        Object o = field.getType().newInstance();
                        toJavaBean(cinvoke,o,false);
                        cinvoke = o;
                    }
                }
                //调用方法写入对象
                Method setMethod = cachMap.getOrDefault(cTarget.getName()+"@"+setMethodName,cTarget.getMethod(setMethodName,
                        new Class[] { field.getType() }));
                cachMap.put(cTarget.getName()+"@"+setMethodName,setMethod);
                setMethod.invoke(target, new Object[] { cinvoke });


            } catch (Exception e) {
//                e.printStackTrace();
            }
        }
    }

    private static boolean isWrapClass(Class clz) {
        if (clz.equals(String.class)){
            return true;
        }
        try {
            return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 带回调函数的集合数据的拷贝(可自定义字段拷贝规则)
     * @param sources : 数据源类
     * @param target : 目标类::new(eg: UserVO::new)
     * @return
     */
    public static void copyListProperties(List<Object> sources, List<Object> target,Class<?> targetType) {
        for (Object source : sources) {
            Object o = null;
            try {
                o = targetType.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            toJavaBean(source, o,false);
            target.add(o);
        }
    }

    /**
     * 获取list的范性
     * @param f list
     * @return
     */
    private static Class<?> getT(Field f){
        Type genericType = f.getGenericType();
        // 如果是泛型参数的类型
        if(genericType instanceof ParameterizedType){
            ParameterizedType pt = (ParameterizedType) genericType;
            //得到泛型里的class类型对象
            return (Class<?>)pt.getActualTypeArguments()[0];
        }
        return null;
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值