我是靠谱客的博主 仁爱小蝴蝶,最近开发中收集的这篇文章主要介绍利用反射比较两个对象是否相等,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

java开发中,Junit做单测是必不可少的一环。然而对于单测结果的比较,仅仅通过Assert断言来比较远远不够。Assert只能比较基本类型,而对于对象是否相等,只能取出对象的值来,一一断言对比。这无疑给开发增加了很多无用的工作。下面简单介绍一个利用反射机制来实现对象比较的例子。话不多说,上代码。

public class ReflectTest {


    public static void main(String[] args) {

        Map<String, Object> m = new HashMap();
        m.put("test","testvalue");
        TestEntity next1 = new TestEntity("testStr",222,m);
        TestEntity tn1 = new TestEntity("1212",999,m);
        tn1.setNext(next1);
        TestEntity next2 = new TestEntity("testStr",222,m);
        TestEntity tn2 = new TestEntity("1212",999,m);
        tn2.setNext(next2);

        Assert.assertEquals(tn1, tn2);
    }
}

在这段代码里面,我创建了一个测试用的实体类,其中包含一个字符串属性,一个整型属性,一个Map属性以及一个实体类属性。通过上面代码可以看到,两个测试用的实体类的属性是一样的,然而使用断言,抛出了断言失败的异常。

Exception in thread "main" java.lang.AssertionError: expected [com.mytest.Reflect.TestEntity@4b1210ee] but found [com.mytest.Reflect.TestEntity@4d7e1886]
	at org.testng.Assert.fail(Assert.java:94)
	at org.testng.Assert.failNotEquals(Assert.java:494)
	at org.testng.Assert.assertEquals(Assert.java:123)
	at org.testng.Assert.assertEquals(Assert.java:165)
	at com.mytest.Reflect.ReflectTest.main(ReflectTest.java:31)

接下来使用反射机制来实现对象的比较。上代码:

private static boolean compareObject(Object o1, Object o2){

        // 记录比较结果
        boolean retFlag = true;

        // 首先判断需要比较的对象是否为null,一个为null,一个不是null时,返回不相等
        if((o1 == null && o2 != null)||(o1 != null && o2 == null)){
            return false;
        }

        // 都为null时,返回相等
        if(o1 ==null && o2==null){
            return true;
        }

        // +++++++++++++++++++++++都不为null时,继续比较+++++++++++++++++++++++++++++++

        // 首先比较两个对象的类型是否一致,类型不一致,直接返回不相等
        if(o1.getClass().isInstance(o2)){


            try {

                // 通过反射获取到需要比较的对象类
                Class clzz = Class.forName(o1.getClass().getName());

                // 获取类对应的属性对象
                Field[] fs = clzz.getDeclaredFields();

                // 依次比较各属性值
                for(Field ftemp : fs){

                    // 获取属性名称
                    String fieldName = ftemp.getName();

                    // 组装属性对应的get方法
                    String methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);

                    // 通过get方法获取属性值
                    Object v1 = clzz.getMethod(methodName).invoke(o1);
                    Object v2 = clzz.getMethod(methodName).invoke(o2);

                    // +++++++++++++++++++此处使用枚举出类型的方式,方法欠佳,仅供参考。+++++++++++++++++
                    // 如果是基本类型或者是集合类型,则直接调用对象的equals方法
                    if(v1 instanceof String || v1 instanceof Integer || v1 instanceof Short || v1 instanceof Long
                            || v1 instanceof Byte || v1 instanceof Character || v1 instanceof Boolean
                            || v1 instanceof Float || v1 instanceof Double || v1 instanceof Map){

                        if(!compareValue(v1, v2)){
                            retFlag = false;
                            break;
                        }
                    }else{

                        // 如果是对象类型,则继续递归调用本方法
                        if(!compareObject(v1, v2)){
                            retFlag = false;
                            break;
                        }

                    }


                }

            } catch (ClassNotFoundException e) {
                System.out.println("fail to compare Objects !");
                retFlag = false;
            } catch (IllegalAccessException e) {
                System.out.println("fail to compare Objects !");
                retFlag = false;
            } catch (InvocationTargetException e) {
                System.out.println("fail to compare Objects !");
                retFlag = false;
            } catch (NoSuchMethodException e) {
                System.out.println("fail to compare Objects !");
                retFlag = false;
            }
        }else{
            retFlag = false;
        }

        return retFlag;
    }

    /**
     * 如果是基本类型或集合类,则直接用equals方法比较
     *
     * @param o1
     * @param o2
     * @return
     */
    private static boolean compareValue(Object o1, Object o2){

        if(o1 ==null || o2==null){
            return false;
        }

        // 集合类特性,实现了equals比较
        if(o1.equals(o2)){
            return true;
        }

        return false;
    }

下面是执行结果:
在这里插入图片描述
欢迎提问并指出更优方案。

最后

以上就是仁爱小蝴蝶为你收集整理的利用反射比较两个对象是否相等的全部内容,希望文章能够帮你解决利用反射比较两个对象是否相等所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部