如何一般地比较整个JavaBean?
我一直试图在org.apache.commons.beanutils库中寻找一个方法/习惯用法来评估两个实例之间的所有属性是否相等,即bean的通用equals()方法。如何一般地比较整个JavaBean?,java,javabeans,Java,Javabeans,我一直试图在org.apache.commons.beanutils库中寻找一个方法/习惯用法来评估两个实例之间的所有属性是否相等,即bean的通用equals()方法。 有没有一个简单的方法来实现这个usnig库?还是我走错了方向? 谢谢。要直接回答您的问题,您可以使用反射对bean进行平等性检查。你需要注意一些障碍 关于equals()和hashcode()的行为有一些规则。这些规则讨论对称性、一致性和自反性,当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都支持它-它没有反射那么昂贵-而且这个答案总体上还是有帮助的-这就是为什么我把它放在这里。。这就是为什么我不从这里开始——我希望这是强制性的,来解释为什么一个人投了反对票——我认为这个答案至少和警告反思可能会很慢的答案一样重要。