最近、スキーマを少し変更して、クラスがスーパークラスから継承するようにしました。問題は、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;
}
このthis.getClass().getSuperClass()
メソッドがnullを返すまでgetSuperClass()
を使用して、親フィールドを取得できます。
したがって、コードを因数分解するのが最善です。 Field
のリストをパラメーターとして受け取り、その中で論理部分を実行する1つのメソッドと、while(superClass != null)
ループを介してフィールドを検索するmainメソッドを実装します。
遅いですが、それは素晴らしい解決策なので、私は私の提案を追加しています。
SpringフレームワークはNiceUtilクラスを提供します_org.springframework.util.ReflectionUtils
_このクラスには、使用できるいくつかのメソッドがあります。 objectClassとsuperClassesから属性のFieldインスタンスを取得するには、ReflectionUtils.findField(clazz, fieldName);
を使用しました
utilの良いところは、例外をスローしないことです。代わりに、無効なものに対してnullを返すため、適切に処理できます。
Apache Commons Langは、@ sp00mのアルゴリズムの実装であるメソッド FieldUtils.getAllFields() を提供します。