2012-05-14 25 views
17

Ho recentemente cambiato il mio schema un po 'in modo che le mie classi ereditino da una super classe, problema è il mio metodo di confronto che genera un log di controllo, usando Java reflect, ora scorre solo attraverso i campi del bambino classe, non la superclasse, c'è un modo per ottenere tutti i CAMPI? o devo lanciarlo nella super classe .....?Come far riflettere Java per individuare i campi nella super classe? non solo la classe attuale

Heres il mio metodo di seguito:

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; 
    } 
+0

NB: Probabilmente non si dovrebbe impostare 'field.setAccessible (false)' per impedire condizioni di gara in ambienti multi-thread ... –

+1

il tuo mezzo è: 'instance.getClass(). GetSuperCLass(). GetDeclaredFields() '? – MJM

+0

Grazie MJM, grazie a tutti, sì, è stato facile come torta! :) – Baconbeastnz

risposta

29

È possibile utilizzare fino this.getClass().getSuperClass() questo metodo getSuperClass() restituisce il valore null per ottenere i campi principali.

Quindi, il migliore sarebbe che si riduca il codice. Implementa un metodo che prende un elenco di Field come parametro e fa la tua parte logica al suo interno, e un metodo principale che cerca i campi attraverso un cicloC.

+2

guardare per il metodo getFilds(), nel mio caso non funziona per la superclasse. Ho avuto successo solo con getDeclaredFilds() –

6

Anche se è tardi, sto aggiungendo il mio suggerimento dato che è una bella soluzione.

Spring framework fornisce una bella classe Util org.springframework.util.ReflectionUtils questa classe ha diversi metodi che possiamo usare. Per ottenere un'istanza Field di un attributo da objectClass e superClass, ho utilizzato ReflectionUtils.findField(clazz, fieldName);

La buona cosa con util è che non genera un'eccezione. Invece restituisce null per quelli non validi, quindi puoi gestirlo con garbo.

Problemi correlati