I need to compare dozens of fields in two objects (instances of the same class), and do some logging and updating in case there are differences. Meta code could look something like this:
if (a.getfield1 != b.getfield1)
log(a.getfield1 is different than b.getfield1)
b.field1 = a.field1
if (a.getfield2!= b.getfield2)
log(a.getfield2 is different than b.getfield2)
b.field2 = a.field2
...
if (a.getfieldn!= b.getfieldn)
log(a.getfieldn is different than b.getfieldn)
b.fieldn = a.fieldn
The code with all the comparisons is very terse, and I would like to somehow make it more compact. It would be nice if I could have a method which would take as a parameter method calls to setter and getter, and call this for all fields, but unfortunately this is not possible with java.
I have come up with three options, each which their own drawbacks.
1. Use reflection API to find out getters and setters
Ugly and could cause run time errors in case names of fields change
2. Change fields to public and manipulate them directly without using getters and setters
Ugly as well and would expose implementation of the class to external world
3. Have the containing class (entity) do the comparison, update changed fields and return log message
Entity should not take part in business logic
All fields are String type, and I can modify code of the class owning the fields if required.
EDIT: There are some fields in the class which must not be compared.
Use Annotations.
If you mark the fields that you need to compare (no matter if they are private, you still don't lose the encapsulation, and then get those fields and compare them. It could be as follows:
In the Class that need to be compared:
@ComparableField
private String field1;
@ComparableField
private String field2;
private String field_nocomparable;
And in the external class:
public <T> void compare(T t, T t2) throws IllegalArgumentException,
IllegalAccessException {
Field[] fields = t.getClass().getDeclaredFields();
if (fields != null) {
for (Field field : fields) {
if (field.isAnnotationPresent(ComparableField.class)) {
field.setAccessible(true);
if ( (field.get(t)).equals(field.get(t2)) )
System.out.println("equals");
field.setAccessible(false);
}
}
}
}
The code is not tested, but let me know if helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With