Вопрос по reflection, field, java – Сравнение значений полей с использованием отражения

5

Я пытаюсь сравнить значения полей двух разных объектов в общем виде. У меня есть функция (см. Ниже), которая принимает два объекта, а затем получает поля, а затем сравнивает поля в цикле и добавляет поля в список, если они не совпадают - это правильный способ сделать это?

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() -Я знаю, что нет такого способа, но, может быть, есть другой способ ???

Поля принадлежат классам, значения хранятся (если не статические) в экземплярах. Что именно вы пытаетесь достичь? khachik
Хорошо, я должен был быть более ясным - я передаю два экземпляра двух объектов - я пытаюсь сравнить два набора данных (списки объектов), которые возвращаются hibernate - но я передаю их в цикле один экземпляр объекта некоторых класс за один раз, чтобы сравнить поля этого экземпляра с некоторым другим экземпляром JonH
@JohH Если вы используете IntelliJ, вы можете генерировать equals () и hashCode () автоматически. Я склонен любить их больше, чем использовать рефлексию для сравнения данных, как с рефлексией вы можетеограничить поля, которые будут сравниваться. Ravi Wallau
@RaviWallau Я думаю, что в этот момент Hibernate завершает вмешательство в эти объекты ... Я запускаю запрос и затем получаю список <Объект>() вернулся из спящего режима. Если бы я хотел сделать это не универсальным способом, я мог бы привести каждый экземпляр в списке, а затем сравнить значения - но это было бы много кода, который можно было бы сделать в общем. JonH

Ваш Ответ

3   ответа
11

который избавит вас от многих хлопот, если вы 'Вы хотите сделать поле путем сравнения полей.

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

Если ты'Вы хотите сравнить поля самостоятельно, проверьтеjava.lang.Class.getDeclaredFields() который даст вам все поля, включая непубличные поля.

Для сравнения значения полей используйтеf.get(qa).equals(f.get(qa4)) В настоящее время вы фактически сравниваете экземпляры полей, а не значения.

Хорошо - я верю, что это работает - но у меня есть быстрый вопрос - так чтоf.get(qa) получит поле "некоторое_имя "»Значение s - так что мне не нужно беспокоиться о порядке полей или о том, что он сравнивает одно и то же поле, верно? JonH
Как getDeclaredFields () помогает, когда мне нужно сравнить значения? JonH
QA и QA4 это весь объект ??? Это сработает - я попробую ... JonH
@JonH Я немного обновил свой ответ. Главное, что вы действительно должны рассмотреть общую библиотеку для этого сравнения. Надеюсь это поможет. tjg184
Предполагая, что это один и тот же тип класса, порядок полей будет одинаковым. tjg184
3

Викисклада BeanUtils может помочь вам, если вы хотите сравнить свойства компонента (значения, возвращаемые получателями) вместо сравнения значений поля.

Однако, если вы хотите придерживаться простого отражения, вам следует:

использованиеClass.getDeclaredFields() вместоClass.getFields(), так как последний возвращает только открытые поля.Поскольку поля зависят только от их класса, вы должны кэшировать результат и хранить поля в переменной static / instance, а не вызыватьgetDeclaredFields() для каждого сравнения.Как только у вас есть объект этого класса (скажем,o), чтобы получить значение некоторого поляf для этого конкретного объекта вам нужно позвонить:.f.get(o)
0

// Если вы хотите иметь несколько полей, а не все поля, используйте это.

ion, 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;
}

Похожие вопросы