如何一般地比较整个Java豆?

2022-09-02 03:41:49

我一直在尝试在 org.apache.commons.beanutils 库中寻找一个方法/成语来评估 2 个实例之间的所有属性是否相等,即 bean 的泛型 equals() 方法。
有没有一种简单的方法来做到这一点,以取代这个库?还是我以错误的方式行事?谢谢。


答案 1

尝试 EqualsBuilder.reflectionEquals() of commons-lang.EqualsBuilder有一组方法可以包括所有字段,所有非瞬态字段以及除某些字段之外的所有字段。

如果所有其他方法都失败了,那么代码可以作为如何实现这一点的一个很好的例子。


答案 2

要直接回答您的问题,您可以使用反射对bean进行相等性检查。您需要注意一些障碍。

有关于 equals() 和 hashcode() 行为的规则。这些规则谈论对称性,一致性和自反性,当你的equals方法基于你传递的另一个对象动态地表现时,这可能很难做到。

有趣的阅读:http://www.geocities.com/technofundo/tech/java/equalhash.html

一般来说,我认为你最好创建自己的哈希码和平等方法。有一些很好的插件可以根据类属性自动为您生成该代码。

说了这么多,这里有一些(旧式的)方法来获取我很久以前写的getter,setter和属性:

private Map getPrivateFields(Class clazz, Map getters, Map setters) {
    Field[] fields = clazz.getDeclaredFields();
    Map m = new HashMap();
    for (int i = 0; i < fields.length; i++) {
        int modifiers = fields[i].getModifiers();
        if (Modifier.isPrivate(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
            String propName = fields[i].getName();
            if (getters.get(propName) != null && setters.get(propName) != null) {
                m.put(fields[i].getName(), fields[i]);
            }
        }
    }
    return m;
}

The Getters:

private Map getGetters(Class clazz) {
    Method[] methods = clazz.getMethods();
    Map m = new HashMap();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName().startsWith("get")) {
            int modifiers = methods[i].getModifiers();
            if (validAccessMethod(modifiers)) {
                m.put(getPropertyName(methods[i].getName()), methods[i]);
            }
        }
    }
    return m;
}

和二传手:

private Map getSetters(Class clazz, Map getters) {
    Method[] methods = clazz.getMethods();
    Map m = new HashMap();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName().startsWith("set")) {
            int modifiers = methods[i].getModifiers();
            String propName = getPropertyName(methods[i].getName());
            Method getter = (Method) getters.get(propName);

            if (validAccessMethod(modifiers) && getter != null) {
                Class returnType = getter.getReturnType();
                Class setType = methods[i].getParameterTypes()[0];
                int numTypes = methods[i].getParameterTypes().length;

                if (returnType.equals(setType) && numTypes == 1) {
                    m.put(propName, methods[i]);
                }
            }
        }
    }
    return m;
}

也许你可以用它来滚动你自己的。

编辑:当然,Aaron Digulla的答案中的反射构建者比我的手提工作要好得多。


推荐