Java比较两个对象中属性值是否相同【使用反射实现】
- 工作小总结
- 时间:2022-03-06 22:50
- 2584人已阅读
简介
在工作中,有些场景下,我们需要对比两个完全一样对象的属性值是否相等。比如接口替换的时候,需要比较新老接口在相同情况下返回的数据是否
🔔🔔🔔好消息!好消息!🔔🔔🔔
有需要的朋友👉:联系凯哥
在工作中,有些场景下,我们需要对比两个完全一样对象的属性值是否相等。比如接口替换的时候,需要比较新老接口在相同情况下返回的数据是否相同。这个时候,我们怎么处理呢?这里凯哥就使用Java的反射类实现。
/** * 字段比较 * @param vo1 主项 * @param vo2 比较项 */ private void compareFiledValue(DownTempMsg vo1, DownTempMsg vo2) { //需要比较的字段 String [] filedArr = new String [] {"title","subTitle","dataMsg","remark","tempType","pline","bookIds","bookNames","downRemark","articleEndRemark","imgRemark", "videoUrl","imgUrl","extend","showDownType","downTypeStyle","headerDownText","footerDownText", "headerDownStyle","contentDownType","authorArr","pseudonym","introductionParagraphExtend","downGuideExtend","tempPercentage"}; String strClazzName = "class java.lang.String"; if(null != vo2){ for(String filed:filedArr){ if("imgCdnUrl".equals(filed)){ log.info("123"); } Object obj1 = PropertyReflectUtil.getProperty(vo1,filed); Object obj2 = PropertyReflectUtil.getProperty(vo2,filed); if(null != obj1 && null != obj2){ String fieldType = PropertyReflectUtil.getPropertyType(vo1,filed); log.info("filed:{},fieldType:{}",filed,fieldType); //比较不同 String obj1Md5 = ""; String obj2Md5 = ""; try { obj1Md5 = MD5.md5(obj1.toString()); obj2Md5 = MD5.md5(obj2.toString()); } catch (Exception e) { log.info("md5异常了。异常信息为:{}",e.getMessage(),e); } //不相同vo2就设置成自己的。相同vo2就设置为空 if(!obj1Md5.equals(obj2Md5)){ log.info("不同,vo2的值就设置成自己的"); PropertyReflectUtil.setProperty(vo2,filed,obj2); }else{ log.info("相同,vo2的值就设置成空"); PropertyReflectUtil.setProperty(vo2,filed,null); } }else{ log.info("其中一个为空.不处理"); } } } }
PropertyReflectUtil工具类:
import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 属性反射 * @author kaigejava */ @Slf4j public class PropertyReflectUtil { private static final String SET_PREFIX = "set"; private static final String IS_PREFIX = "is"; private static final String GET_PREFIX = "get"; static String regex=".*\\d+.*"; /** * 判断字符串中是否包含数字 * @return */ public static boolean strContainsNum(String str){ if(StringUtils.isBlank(str)){ return false; } Pattern pattern=Pattern.compile(regex); Matcher matcher=pattern.matcher(str); if(matcher.matches()){ return true; } return false; } /** * 根据需求,定制 自己的get和set方法 * @param clazz * @param propertyName * @return */ public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String propertyName) { Method setMethod = null; Method getMethod = null; PropertyDescriptor pd = null; try { // 根据字段名来获取字段 Field field = clazz.getDeclaredField(propertyName); if (field != null) { // 构建方法的后缀 String methodEnd = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); setMethod = clazz.getDeclaredMethod(SET_PREFIX + methodEnd, new Class[] { field.getType() }); // 构建get 方法 getMethod = clazz.getDeclaredMethod(GET_PREFIX + methodEnd, new Class[] {}); // 构建一个属性描述器 把对应属性 propertyName 的 get 和 set 方法保存到属性描述器中 pd = new PropertyDescriptor(propertyName, getMethod, setMethod); } } catch (Exception ex) { log.error("getPropertyDescriptor error,msg:"+ex.getMessage()); } return pd; } public static PropertyDescriptor getPropertyDescriptor2(Class<?> clazz, String propertyName) {//使用 PropertyDescriptor 提供的 get和set方法 try { return new PropertyDescriptor(propertyName, clazz); } catch (IntrospectionException e) { log.error(" getPropertyDescriptor2 error,msg:"+e.getMessage()); } return null; } /** * set值 * @param obj * @param propertyName * @param value */ public static void setProperty(Object obj, String propertyName, Object value) { // 获取对象的类型 Class<?> clazz = obj.getClass(); //字段中的下划线处理 propertyName = formatProperty(propertyName); // 获取 clazz类型中的propertyName的属性描述器 PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName); // 从属性描述器中获取 set 方法 Method setMethod = pd.getWriteMethod(); try { // 调用 set 方法将传入的value值保存属性中去 setMethod.invoke(obj, new Object[] { value }); } catch (Exception e) { log.error(" setProperty error,msg:"+e.getMessage()); } } /** * 获取值 * @param obj * @param propertyName * @return */ public static Object getProperty(Object obj, String propertyName) { // 获取对象的类型 Class<?> clazz = obj.getClass(); //字段中的下划线处理 propertyName = formatProperty(propertyName); // 获取clazz类型中的propertyName的属性描述器 PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName); // 从属性描述器中获取 get 方法 Method getMethod = pd.getReadMethod(); Object value = null; try { // 调用方法获取方法的返回值 value = getMethod.invoke(obj, new Object[] {}); } catch (Exception e) { log.error(" getProperty error,msg:{},propertyName:{}",e.getMessage(),propertyName); } return value; } /** * 根据对象及属性名称获取到对应属性的类型 * @param obj * @param propertyName * @return */ public static String getPropertyType(Object obj, String propertyName){ // 获取对象的类型 Class<?> clazz = obj.getClass(); String type = ""; try { // 根据字段名来获取字段 Field field = clazz.getDeclaredField(propertyName); if (field != null) { type = field.getGenericType().toString(); } } catch (Exception ex) { log.error("getPropertyType error,msg:"+ex.getMessage()); } return type; } public static String formatProperty(String propertyName) { if (propertyName.contains("_")) { String[] tmp = propertyName.split("_"); StringBuilder sb = new StringBuilder(); sb.append(tmp[0]); for (int i = 1; i < tmp.length; i++) { sb.append(tmp[i].substring(0, 1).toUpperCase()).append(tmp[i].substring(1)); } return sb.toString(); } else { return propertyName; } } }