it-swarm.com.ru

Как заставить Java задуматься о точечных полях в суперклассе? не только фактический класс

Недавно я немного изменил свою схему, поэтому мои классы наследуются от суперкласса, проблема в том, что мой метод сравнения, который генерирует журнал аудита с использованием отражения Java, теперь выполняет только циклы по полям дочернего класса, а не суперкласса. Есть ли способ получить все поля? или мне нужно отлить это в супер класс .....?

Вот мой метод ниже:

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;
    }
18
Baconbeastnz

Вы можете использовать this.getClass().getSuperClass(), пока этот метод getSuperClass() не вернет null, чтобы получить родительские поля.

Таким образом, самое лучшее, что вы факторизируете свой код. Реализуйте один метод, который принимает список Field в качестве параметра, и выполняйте в нем свою логическую часть, и основной метод, который ищет поля с помощью цикла while(superClass != null).

32
sp00m

Хотя уже поздно, я добавляю свое предложение, так как это хорошее решение .

Spring Framework предоставляет класс Nice Util org.springframework.util.ReflectionUtils этот класс имеет несколько методов, которые мы можем использовать . Чтобы получить экземпляр Field атрибута из objectClass и superClasses, я использовал ReflectionUtils.findField(clazz, fieldName); 

Хорошая вещь с утилитой - это не исключение. Вместо этого он возвращает ноль для недействительных, так что вы можете обработать это изящно.

10
mds404

Apache Commons Lang предоставляет метод FieldUtils.getAllFields () , который является реализацией алгоритма @ sp00m.

1
Václav Kužel