Java - 使用反射的比较字段

时间:2017-06-23 09:40:33

标签: java

我需要比较两个对象的所有字段并返回差异数。

伪代码如下所示:

Out of range exception

字段具有相同的名称,因为我想比较同一类的对象。

我不能使用标准的等号来做到这一点,因为Foo有很多字段,如果语句我写得太多了。

我如何使用反射来做到这一点?

1 个答案:

答案 0 :(得分:2)

正如评论中所提到的,使用反射来获取所有类成员是一个坏主意。这应该可以解决您的要求:

public <T> int countDiff(T t1, T t2) throws Exception {
    int diffCount = 0;
    Class<? extends Object> tClass = t1.getClass();
    for (Field field : tClass.getDeclaredFields()) {
        field.setAccessible(true);
        Object value1 = field.get(t1);
        Object value2 = field.get(t2);
        if (!isEqual(value1, value2)) {
            diffCount++;
        }
    }
    return diffCount;
}

private boolean isEqual(Object v1, Object v2) {
    return (v1 == null && v2 == null) || (v1 != null && v1.equals(v2));
}

一个安静的更好的解决方案是在getter上循环(但这仍然是一个坏主意:

public <T> int countDiff(T t1, T t2) throws Exception {
    int diffCount = 0;
    Class<? extends Object> tClass = t1.getClass();
    for (Method method : tClass.getMethods()) {
        if (!isGetter(method)) {
            continue;
        }
        Object value1 = method.invoke(t1);
        Object value2 = method.invoke(t2);
        if (!isEqual(value1, value2)) {
            diffCount++;
        }
    }
    return diffCount;
}

private boolean isGetter(Method m) {
    boolean name = m.getName().startsWith("get") || m.getName().startsWith("is");
    return name && m.getParameterTypes().length == 0 && m.getReturnType() != Void.TYPE;
}

private boolean isEqual(Object v1, Object v2) {
    return (v1 == null && v2 == null) || (v1 != null && v1.equals(v2));
}

编辑感谢@tobias_k:添加了布尔值的is方法

相关问题