24

我最近改变了我的模式,所以我的类从一个超类继承,问题是我的比较方法生成审计日志,使用 Java 反射,现在只循环通过子类的字段,而不是超类,是有没有办法获得所有的FIELDS?还是我需要将其转换为超级类.....?

下面是我的方法:

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;
    }
4

3 回答 3

40

您可以使用this.getClass().getSuperClass()直到此getSuperClass()方法返回 null 来获取父字段。

所以,最好的办法是分解你的代码。实现一个将列表作为参数并在其中执行逻辑部分的方法,以及一个通过循环Field搜索字段的 main 方法。while(superClass != null)

于 2012-05-14T09:45:52.000 回答
13

虽然已经很晚了,但我正在添加我的建议,因为它是一个很好的解决方案。

Spring 框架提供了一个很好的 Util 类 org.springframework.util.ReflectionUtils,这个类有几个我们可以使用的方法。为了从 objectClass 和 superClasses 中获取属性的 Field 实例,我使用ReflectionUtils.findField(clazz, fieldName);

了 util 的好处是它不会引发异常。相反,它为无效的返回 null,因此您可以优雅地处理它。

于 2016-12-06T23:06:50.987 回答
5

Apache Commons Lang 提供了一个FieldUtils.getAllFields()方法,它是 @sp00m 算法的实现。

于 2018-10-03T07:27:00.137 回答