JAVA拷贝对象属性的四种方案

原创  郑建华   2020-07-14   54人阅读  0 条评论

JAVA拷贝对象属性的几种方案

1、利用反射进行属性的复制

2、使用BeanUtils.copyProperties方法进行属性复制(注意,支持两种工具org.apache.commons.beanutils.BeanUtils和org.springframework.beans.BeanUtils )

关于此方法的坑,请参考文章《BeanUtils.copyProperties的两个坑》

3、使用BeanCopier.create方法进行属性复制

4、JSON互转

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import org.springframework.beans.BeanUtils;
import org.springframework.cglib.beans.BeanCopier;
import com.alibaba.fastjson.JSON;

public class BeanOperationUtils {

	public static void main(String[] args) {
		try {
			Parent parent = new Parent("LA", new Date());
			System.out.println("这是原本的parent:" + parent);
			Parent parentCopy = new Parent();
			parentCopy = parent;
			// 这种复制修改会造成parent对象的数据进行修改
			parentCopy.setParentName("WA");
			System.out.println("这是修改过的parent:" + parent);
			System.out.println("这是parentCopy:" + parentCopy);

			// 方法一:利用反射进行属性的复制
			Child child1 = new Child();
			copyReflex(parent, child1);
			System.out.println("copyReflex:" + child1);

			// 方法二: 使用BeanUtils.copyProperties方法进行属性复制
			Child child2 = new Child();
			copyProperties(parent, child2);
			System.out.println("copyProperties:" + child2);

			// 方法三: 使用BeanCopier.create方法进行属性复制
			Child child3 = new Child();
			copyBeanCopier(parent, child3);
			System.out.println("copyBeanCopier:" + child3);

			// 方法四:JSON互转
			Child child4 = new Child();
			child4 = (Child) copyJson(parent, child4);
			System.out.println("copyJson:" + child4);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 反射(子类复制父类的属性值)
	 * @param parent 父类
	 * @param child  子类
	 * @throws Exception
	 */
	public static <T> void copyReflex(T parent, T child) throws Exception {
		if (child.getClass().getSuperclass() != parent.getClass()) {
			throw new Exception("child 不是 parent 的子类");
		}
		Class<?> parentClass = parent.getClass();
		Field[] declaredFields = parentClass.getDeclaredFields();
		for (int i = 0; i < declaredFields.length; i++) {
			Field field = declaredFields[i];
			Method method = parentClass.getDeclaredMethod("get" + upperHeadChar(field.getName()));
			Object obj = method.invoke(parent);
			field.setAccessible(true);
			field.set(child, obj);
		}
	}

	/**
	 * 对象属性拷贝 
	 * 将源对象的属性拷贝到目标对象
	 * @param source 源对象
	 * @param target 目标对象
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 */
	public static void copyProperties(Object source, Object target)
			throws IllegalAccessException, InvocationTargetException {
		BeanUtils.copyProperties(source, target);
	}

	/**
	 * 使用BeanCopier.create方法进行属性复制 耗时最少,不使用转换器时,属性类型不同时无法复制,使用转换器后,耗时会相对变长。
	 * 可以用缓存解决性能瓶颈问颗(高并发的时候考虑)
	 * @param source 源对象
	 * @param target 目标对象
	 * @throws Exception
	 */
	public static void copyBeanCopier(Object source, Object target) throws Exception {
		// 第三个参数表示是否使用转换器,false否,true是
		BeanCopier beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
		beanCopier.copy(source, target, null);// 第三个参数是转换器,可自定义一个转换器,对属性不一致的对象属性进行转换
	}

	/**
	 * JSON互转
	 * @param source 源对象
	 * @param target 目标对象
	 * @return Object
	 * @throws Exception
	 */
	public static Object copyJson(Object source, Object target) throws Exception {
		String parentJson = JSON.toJSONString(source);
		target = JSON.parseObject(parentJson, target.getClass());
		return target;
	}

	/** 首字母转大写 */
	public static String upperHeadChar(String in) {
		String head = in.substring(0, 1);
		String out = head.toUpperCase() + in.substring(1, in.length());
		return out;
	}}/** 父类 */class Parent {
	private String parentName;
	private Date date;

	public Parent() {
	}

	public Parent(String parentName, Date date) {
		super();
		this.parentName = parentName;
		this.date = date;
	}

	public String getParentName() {
		return parentName;
	}

	public void setParentName(String parentName) {
		this.parentName = parentName;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	@Override	public String toString() {
		String date = getDate() == null ? null : DateUtils.formatDateToString(getDate(), DateUtils.DATE_FULL_STR);
		return "父类名字:" + this.parentName + ",时间:" + date;
	}}/** 子类 */class Child extends Parent {
	private int id;
	private String childName;

	public Child() {
	}

	public Child(String childName, String date) {
		super();
		this.childName = childName;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getChildName() {
		return childName;
	}

	public void setChildName(String name) {
		this.childName = name;
	}

	@Override	public String toString() {
		String date = getDate() == null ? null : DateUtils.formatDateToString(getDate(), DateUtils.DATE_FULL_STR);
		return "\n\t父类名字:" + getParentName() + ",时间:" + date + ";   子类id:" + this.id + ",名字:" + this.childName;
	}}

运行结果:

image.png

本文地址:https://www.zjh336.cn/?id=1901
版权声明:本文为原创文章,版权归 郑建华 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?