How to get Java reflect to spot fields in the super class? not just the actual class [duplicate]

StackOverflow https://stackoverflow.com/questions/10580866

  •  08-06-2021
  •  | 
  •  

Question

I've recently changed my schema a bit so my classes inherit from a super class, problem is my comparison method which generates an audit log, using Java reflect, is now only looping through the fields of the child class, not the superclass, is there a way to get all the FIELDS? or do I need to cast it into the super class.....?

Heres my method below:

public static <T> String GenerateChangeLogForEntity(T old, T updated) {
        String text = "";
        try {
            Field[] fields = old.getClass().getDeclaredFields();
            if(fields != null) {
                BaseController.getLogger().info("Z1 num fields:"+fields.length);
                for (Field field : fields) {
                    if(field.isAnnotationPresent(Column.class)) {
                        String fieldName = field.getName();
                        BaseController.getLogger().info(field.getName());
                        if(field.isAnnotationPresent(Variation.class)) {
                            Variation v = field.getAnnotation(Variation.class);
                            fieldName = v.friendlyName();
                        }
                        field.setAccessible(true);
                        if(field.get(old) != null && field.get(updated) != null) {
                            if(!(field.get(old)).equals(field.get(updated))) {
                                text += "<p><span class=\"field-name\">"+fieldName+"</span> changed from: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(old))+"</strong>  to: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(updated)) + "</strong></p>";
                            }
                        }
                        if(field.get(old) == null && field.get(updated) != null) {
                            text += "<p><span class=\"field-name\">"+fieldName+"</span> changed from: <strong>empty</strong> to: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(updated)) + "</strong></p>";
                        }
                        if(field.get(old) != null && field.get(updated) == null) {
                            text += "<p><span class=\"field-name\">"+fieldName+"</span> changed from: <strong>"+GetFriendlyFieldValueForChangeLog(field.get(updated))+"</strong> to <strong>empty</strong>" + "</p>";
                        }
                        field.setAccessible(false);
                    }
                }
            }
        } catch(IllegalAccessException e) {}
        return text;
    }
Was it helpful?

Solution

You can use this.getClass().getSuperClass() until this getSuperClass() method returns null to get the parent fields.

So, the best would be that you factorize your code. Implement one method that takes a list of Field as parameter and do your logical part within it, and a main method that search for fields through a while(superClass != null) loop.

OTHER TIPS

Though it's late, I'm adding my suggestion since it's a nice solution.

Spring framework provide a nice Util class org.springframework.util.ReflectionUtils this class has several methods which we can use. To get a Field instance of an attribute from objectClass and superClasses I used ReflectionUtils.findField(clazz, fieldName);

Good thing with util is it doesn't throw an exception. Instead it returns null for invalid ones, so you can handle it gracefully.

Apache Commons Lang provides a method FieldUtils.getAllFields() which is an implementation of @sp00m's algorithm.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top