做项目的过程中正好需要比较两个对象是否相等,通过导师的指点,运用反射的原理完成了这个功能。突然发现,反射是一个很有用的工具,可以解决很多原来不能解决的事情。
判断两个对象是否相等
两个对象的相等当然可以通过重写equals() 和 hashcode() 进行实现,但是对于在项目中已经封装好的,而并没有重写equals() 和 hashcode() 方法的类,使用反射就可以判断两个对象是否相等了。
public static String compare2Obj(AccountDto obj1, AccountDto obj2) {
Class<?> obj1Class = obj1.getClass();
Class<?> obj2Class = obj2.getClass();
Field[] obj1Field = obj1Class.getDeclaredFields();
Field[] obj1SupField = obj1Class.getSuperclass().getDeclaredFields();
int obj1FieLen = obj1Field.length;
int obj1SupFieLen = obj1SupField.length;
// getDeclaredFields() 不能够返回父级的对象,所以需要调用superclass 然后进行反射
obj1Field=HelperUtil.combineArray(Field.class, obj1Field,obj1SupField);
String newStr = "";
String tempStr = "";
// 使得obj1Field 方法有序
HelperUtil.sortField(obj1Field);
try {
for (Field field1 : obj1Field) {
if (Modifier.isFinal(field1.getModifiers())) {
continue;
}
String t = generateGetMethod(field1.getName());
Object object1 = obj1Class.getMethod(generateGetMethod(field1.getName())).invoke(obj1);
Object object2 = obj2Class.getMethod(generateGetMethod(field1.getName())).invoke(obj2);
tempStr = checkCategory(field1.getName(),obj1.getAccountType());
// 有一个对象不为空的情况
if (object1 == null ^ object2 == null) {
if (!"".equals(tempStr)) {
newStr = newStr + tempStr + " 变更前: " + object1 + " 变更后: " + object2 + " ; ";
}
} else if (object1 == null && object2 == null) {
continue;
} else if (!object1.equals(object2)) {
if (!"".equals(tempStr)) {
newStr = newStr + tempStr + " 变更前: " + object1 + " 变更后: " + object2 + " ; ";
}
}
}
} catch (NoSuchMethodException e) {
new FamRuntimeException(e);
} catch (IllegalAccessException e) {
new FamRuntimeException(e);
} catch (InvocationTargetException e) {
new FamRuntimeException(e);
}
return newStr;
}
自己判断两个对象值是否相等,一定要注意几点 :
- 判断对象是否为空,为空则看情况,如果都为null值,则返回true,如果其中一个不为null值,则返回false,如果不进行对象为空判断,会报空指针异常。
- 注意属性之间判断相等的语句是不一致的,如果为基本类型,则用 == 方法比较,如果为对象,则用equals(),基本类型采用equals进行判断,会报MethodNotFound异常。
- 反射返回的field 是打乱顺序的,一定要调整field顺序。
我们也可以使用apache自带的equalsBuilder 去重写对象的equals方法,
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
或者我们可以直接采用EqualsBuilder的方法去实现两个对象之间的比较。
public void RefEqu() {
RefEntity inst1 = new RefEntity();
inst1.nestedClass = new RefEntity();
inst1.nestedClasstvalue = 2;
RefEntity inst2 = new RefEntity();
inst2.nestedClass = new RefEntity();
inst2.nestedClass.intVal = 2;
boolean isEqual = EqualsBuilder.reflectionEquals(inst1.nestedClass, inst2.nestedClass);
isEqual = EqualsBuilder.reflectionEquals(inst1, inst2);
}