反射应用:比较两个对象属性的不同

本文介绍了一种利用Java反射机制高效记录对象属性修改的方法。通过对比源对象和目标对象的属性值,能够准确捕捉到被修改的具体内容,并支持指定关键属性进行比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在工作中遇到这样一个问题: 在操作人修改单据时,需要记录此次修改的内容。此问题,最简单的方法就是对修改前和修改后的对象属性一一比较,记录修改内容。如果此单据有几十个属性时,一一比较的方法较繁琐。此时,我们用反射的方法来解决。

package com.xtli.controller.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

import org.springframework.util.StringUtils;

public class ReflectUtils {
	/**
	 * Description: 获取修改内容
	 */
	public static String packageModifyContent(Object source, Object target) {
		StringBuffer modifyContent = new StringBuffer();
		if(null == source || null == target) {
			return "";
		}
		//取出source类
		Class<?> sourceClass = source.getClass();
		
		Field[] sourceFields = sourceClass.getDeclaredFields();
		for(Field srcField : sourceFields) {
			String srcName = srcField.getName();			
			//获取srcField值
			String srcValue = getFieldValue(source, srcName) == null ? "" : getFieldValue(source, srcName).toString();
			//获取对应的targetField值
			String targetValue = getFieldValue(target, srcName) == null ? "" : getFieldValue(target, srcName).toString();
			if(StringUtils.isEmpty(srcValue) && StringUtils.isEmpty(targetValue)) {
				continue;
			}
			if(!srcValue.equals(targetValue)) {
				modifyContent.append(srcName + "由‘" + targetValue + "’修改为‘" + srcValue + "’;");
			}
			
		}
		return modifyContent.toString();
	}
	/**
	 * Description: 获取Obj对象的fieldName属性的值
	 */
	private static Object getFieldValue(Object obj, String fieldName) {
		Object fieldValue = null;
		if(null == obj) {
			return null;
		}
		Method[] methods = obj.getClass().getDeclaredMethods();
		for (Method method : methods) {
			String methodName = method.getName();
			if(!methodName.startsWith("get")) {
				continue;
			}
			if(methodName.startsWith("get") && methodName.substring(3).toUpperCase().equals(fieldName.toUpperCase())) {
                 try {
                	 fieldValue = method.invoke(obj, new Object[] {});
                 } catch (Exception e) {
                	System.out.println("取值出错,方法名 " + methodName);
                    continue;
                 }
			}
		}
		return fieldValue;
	}
}

此方法可以记录下source对象和target对象全部属性的不同,解决问题。

以上方法记录的是两个对象的全部属性,如果我们只想记录部分关键属性,怎么办?只需要增加一个Map参数即可,此Map参数是关键属性的映射集合。(用map而不是set,是因为可以给属性映射一个别名)。改进后的packageModifyContent方法如下:

/**
	 * Description: 获取修改内容
	 */
	public static String packageModifyContent(Object source, Object target, Map<String,String> comparedProperties) {
		StringBuffer modifyContent = new StringBuffer();
		if(null == source || null == target) {
			return "";
		}
		//取出source类
		Class<?> sourceClass = source.getClass();
		
		Field[] sourceFields = sourceClass.getDeclaredFields();
		for(Field srcField : sourceFields) {
			String srcName = srcField.getName();
			//获取此属性值。条件: 1 比较所有属性; 2 比较的属性在比较集合中
			if(null == comparedProperties || (null != comparedProperties && comparedProperties.containsKey(srcName))) {
				
				//获取srcField值
				String srcValue = getFieldValue(source, srcName) == null ? "" : getFieldValue(source, srcName).toString();
				//获取对应的targetField值
				String targetValue = getFieldValue(target, srcName) == null ? "" : getFieldValue(target, srcName).toString();
				if(StringUtils.isEmpty(srcValue) && StringUtils.isEmpty(targetValue)) {
					continue;
				}
				if(!srcValue.equals(targetValue)) {
					modifyContent.append(comparedProperties.get(srcName) + "由‘" + targetValue + "’修改为‘" + srcValue + "’;");
				}
			}
		}
		return modifyContent.toString();
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值