24

最近スキーマを少し変更したので、クラスはスーパークラスから継承されます。問題は、Java Reflect を使用して監査ログを生成する比較メソッドが、スーパークラスではなく子クラスのフィールドのみをループすることです。すべての 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

このメソッドが null を返すthis.getClass().getSuperClass()まで使用して、親フィールドを取得できます。getSuperClass()

したがって、コードを因数分解するのが最善です。パラメータとしてのリストを取り、その中で論理的な部分を実行する 1 つのメソッドと、ループ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 に答える