I am trying to compare the field values of two different objects in a generic way. I have a function (seen below) that takes in two Objects and then gets the fields and then compares the fields in a loop and adds the fields to a list if they are not the same - is this the proper way to do this?
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();
}
}
I was googling and I saw that C# had like a PropertyInfo Class - does Java have anything like that?
ALSO, is there a way to do like f.getFieldValue()
-I know there is no method like this but maybe there is another way???
You might check out org.apache.commons.lang.builder.EqualsBuilder which will save you a lot of this hassle if you're wanting to do a field by field comparison.
org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals(Object, Object)
If you're wanting to compare fields yourself, check out java.lang.Class.getDeclaredFields()
which will give you all the fields including non-public fields.
To compare the value of the fields use f.get(qa).equals(f.get(qa4))
Currently, you are actually comparing the field instances and not the values.
Libraries like commons-beanutils can help you if you want to compare bean properties (values returned by getters) instead of comparing field values.
However, if you want to stick with plain reflection, you should:
- Use
Class.getDeclaredFields()
instead of Class.getFields()
, as the latter only returns the public fields.
- Since fields only depend on their class, you should cache the result and keep the fields in a static / instance variable rather than invoking
getDeclaredFields()
for each comparison.
- 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)
.
// 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;
}