0

I have a util that gets a lot of couples of objects (with the same ancestors).
The util than publishes them to other clients. I want to add a representation of the differences (e.g. a map/list with all the "dirty" fields).

How can I do it generically? Or should I implement it for each object?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Bick
  • 17,833
  • 52
  • 146
  • 251
  • You might want to look into [reflection](http://docs.oracle.com/javase/tutorial/reflect/), or [Apache Commons BeanUtils](http://commons.apache.org/proper/commons-beanutils/). The answers to [this question](http://stackoverflow.com/q/6099040/851811) may also be useful, it looks like this one is a duplicate of it. – Xavi López Jul 28 '14 at 09:53

2 Answers2

1

My 2 cents.

  1. You could resolve to the reflection package, get the getters of the object (assumes your data object is properly encapsulated) and try to compare the results. But the performance really sucks and this won't apply for any production system.

  2. If you have control on the data object classes, implement your own interface and also generate your own data objects. Use enum to identify each fields and have a specific enum class for each of your data object classes. This is best done with a code generator for this interface and related methods.

Alex Suo
  • 2,977
  • 1
  • 14
  • 22
  • Reflection is not fast but "really sucks" is a stretch. Depending on the use-case it may well be acceptable. – Tim B Jul 28 '14 at 10:03
  • I agree. Maybe because I have been working with high performance system too much :-) However looking at his application, I suspect he is doing something about data objects, and it's reasonable to assume such comparison is done a lot. But as you said, nothing absolute. – Alex Suo Jul 28 '14 at 10:05
  • What kind of code generator can usually be used for this scenario? – Bick Nov 03 '14 at 13:55
0

is this what you want? java doc: Discovering Class Members

public static <T> List<Field> compare(T o1, T o2) throws IllegalAccessException {

    List<Field> differentFields = new LinkedList<>();
    if(o1 != o2){
        Class clazz = o1.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for(Field f: fields){
            boolean accessible = f.isAccessible();
            if(! accessible){
                f.setAccessible(true);
            }
            Object o1f = f.get(o1);
            Object o2f = f.get(o2);
            if(!Objects.equals(o1f, o2f)){
                differentFields.add(f);
            }
            f.setAccessible(accessible);
        }
    }
    return differentFields;
}
lowatt
  • 363
  • 2
  • 18