在工作中,有些场景下,我们需要对比两个完全一样对象的属性值是否相等。比如接口替换的时候,需要比较新老接口在相同情况下返回的数据是否相同。这个时候,我们怎么处理呢?这里凯哥就使用Java的反射类实现。
代码语言:javascript复制/**
* 字段比较
* @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("其中一个为空.不处理");
}
}
}
}
代码语言:javascript复制PropertyReflectUtil工具类:
代码语言:javascript复制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;
}
}
}