如何一般地比较整个JavaBean?

如何一般地比较整个JavaBean?,java,javabeans,Java,Javabeans,我一直试图在org.apache.commons.beanutils库中寻找一个方法/习惯用法来评估两个实例之间的所有属性是否相等,即bean的通用equals()方法。 有没有一个简单的方法来实现这个usnig库?还是我走错了方向? 谢谢。要直接回答您的问题,您可以使用反射对bean进行平等性检查。你需要注意一些障碍 关于equals()和hashcode()的行为有一些规则。这些规则讨论对称性、一致性和自反性,当equals方法基于您传递的另一个对象动态运行时,这可能很难做到 有趣的阅读:

我一直试图在org.apache.commons.beanutils库中寻找一个方法/习惯用法来评估两个实例之间的所有属性是否相等,即bean的通用equals()方法。
有没有一个简单的方法来实现这个usnig库?还是我走错了方向?
谢谢。

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

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

有趣的阅读:

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

说到这里,这里有一些(老式的)获取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;
}
private Map getPrivateFields(类clazz、Map getter、Map setter){
Field[]fields=clazz.getDeclaredFields();
Map m=新的HashMap();
for(int i=0;i
获得者:

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;
}
私有映射getter(类clazz){
方法[]methods=clazz.getMethods();
Map m=新的HashMap();
for(int i=0;i
二传手:

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;
}
私有映射getsetter(类clazz,映射getter){
方法[]methods=clazz.getMethods();
Map m=新的HashMap();
for(int i=0;i
也许你可以用这个来做你自己的

编辑:当然,这本书比我的手工作品要好得多

试试看。EqualsBuilder有一组方法,包括所有字段、所有非瞬态字段和除某些字段外的所有字段


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

如上所述,基于反射的实现可以满足您的需要。我只是想警告你们,反射是相当昂贵的,这样的实现可能会相当缓慢。如果你只是需要偶尔比较一下,你会没事的。但是,如果您有庞大的数据集和频繁的相等性检查(例如,过滤大表),您可能会遇到麻烦。

或者,虽然不是对您的问题的直接回答,但可能是对您的问题的回答(即,在超快速的情况下,省去编写样板代码的工作)

如果使用Eclipse,以下步骤将为您自动生成hashCode和equals:

源代码>生成哈希代码并等于

然后选择字段,这非常有效!:D

干杯,我希望它能帮助那些来这里的人节省一些时间来编写样板


PS:我相信其他流行的IDE一定也有类似的特性

说得对。jguru在网上有一个很好的比较:布尔getter被称为isFoo(),因此代码需要在getGetters()中进行一个小的增强。请注意,这不是递归的——因此,如果您有嵌套的bean(即,一个bean的属性是另一个bean),那么它们需要自己实现equals
reflectionEquals
仅对每个属性调用
equals
,它不会进一步反映到类中。@artbristol:+1但要小心递归equals:当bean形成循环时,您很容易陷入循环中。另外,ReflectionDiffBuilder也很有用,可用于查找差异,这可能是本文感兴趣的内容;我真的很想知道为什么这个选项被否决为-1。这是生成此类方法的一种非常快速的方法。而且大多数IDE都支持它-它没有反射那么昂贵-而且这个答案总体上还是有帮助的-这就是为什么我把它放在这里。。这就是为什么我不从这里开始——我希望这是强制性的,来解释为什么一个人投了反对票——我认为这个答案至少和警告反思可能会很慢的答案一样重要。