11

我正在尝试以通用方式比较两个不同对象的字段值。我有一个函数(见下文),它接受两个对象,然后获取字段,然后在循环中比较字段,如果字段不相同,则将字段添加到列表中 - 这是正确的方法吗?

public void compareFields(Object qa, Object qa4) throws FieldsNotEqualException
{

  Field[] qaFields = qa.getClass().getFields();
  Field[] qa4Fields = qa4.getClass().getFields();

  for(Field f:qaFields) 
  { 

    for(Field f4:qa4Fields)
    {
       if(f4.equals(f))
       {
           found = true;
           break;
       }
       else
       {
           continue;
       }
    }
  }

 if(!found)
 {
    report.add(/*some_formatted_string*/) //some global list 
    throw new FieldsNotEqualException();
 }
}

我在谷歌上搜索,发现 C# 有一个 PropertyInfo 类——Java 有类似的东西吗?另外,有没有办法像f.getFieldValue()- 我知道没有这样的方法,但也许还有另一种方法???

4

3 回答 3

16

您可以查看 org.apache.commons.lang.builder.EqualsBuilder 如果您想逐个字段进行比较,这将为您省去很多麻烦。

org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals(Object, Object)

如果您想自己比较字段,请查看java.lang.Class.getDeclaredFields()哪个将为您提供所有字段,包括非公共字段。

要比较字段的值,请使用f.get(qa).equals(f.get(qa4)) 当前,您实际上是在比较字段实例而不是值。

于 2012-11-21T15:10:46.727 回答
3

如果您想比较 bean 属性(getter 返回的值)而不是比较字段值,commons-beanutils 之类的库可以为您提供帮助。

但是,如果您想坚持使用普通反射,您应该:

  1. 使用Class.getDeclaredFields()代替Class.getFields(),因为后者只返回公共字段。
  2. 由于字段仅依赖于它们的类,因此您应该缓存结果并将字段保存在静态/实例变量中,而不是getDeclaredFields()为每次比较调用。
  3. Once you have an object of that class (say o), in order to get the value of some field f for that particular object, you need to call: f.get(o).
于 2012-11-21T15:16:44.137 回答
0

// If you want to have some fields, not all field then use this.

  public boolean compareObject(Object object) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException 
{

 String[] compareFields = { "fieldx", "fieldy","fieldz", "field15",
        "field19"}; // list of all we need 
for(String s : compareFields) {
Field field = DcrAttribute.class.getDeclaredField(s); // get a list of all fields for this class
    field.setAccessible(true);
    if(!field.get(this).equals(field.get(object))){  //if values are not equal          
    return true;    
    }       

    }

    return false;
}
于 2018-10-30T14:38:06.753 回答