使用反射比较两个对象是否相等

本文介绍了在项目中如何使用反射来比较两个对象是否相等,特别是在没有重写equals()和hashcode()方法的情况下。通过反射,可以避免空指针异常,正确处理基本类型和对象类型的比较,并注意字段顺序。同时提到了Apache的equalsBuilder作为替代解决方案。

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

做项目的过程中正好需要比较两个对象是否相等,通过导师的指点,运用反射的原理完成了这个功能。突然发现,反射是一个很有用的工具,可以解决很多原来不能解决的事情。

判断两个对象是否相等

两个对象的相等当然可以通过重写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;
    }

自己判断两个对象值是否相等,一定要注意几点 :

  1. 判断对象是否为空,为空则看情况,如果都为null值,则返回true,如果其中一个不为null值,则返回false,如果不进行对象为空判断,会报空指针异常。
  2. 注意属性之间判断相等的语句是不一致的,如果为基本类型,则用 == 方法比较,如果为对象,则用equals(),基本类型采用equals进行判断,会报MethodNotFound异常。
  3. 反射返回的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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值