2012-05-14 26 views
17

Kısa bir süre önce sınıflarım bir süper sınıftan miras alabilmem için şemalarımı biraz değiştirdim, problem, Java yansıtmayı kullanarak bir denetim günlüğü oluşturan karşılaştırma yöntemim artık sadece çocuk alanları arasında dönüyor sınıf, sınıf değil, tüm ALANLARI almak için bir yol var mı? ya da süper sınıfa girmem gerekiyor .....?Java, süper sınıftaki alanlara nasıl yansıtılır? sadece gerçek sınıf değil

İşte aşağıda benim yöntemi: Bu getSuperClass() yöntem ebeveyn alan almak için boş dönünceye kadar

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: Muhtemelen çok alanlı ortamlarda yarış koşullarını önlemek için 'field.setAccessible (false)' ayarlamamalısınız ... –

+1

araçlarınız: 'instance.getClass(). GetSuperCLass(). GetDeclaredFields() '? – MJM

+0

Teşekkürler MJM, herkese teşekkürler, bu pasta kadar kolay oldu! :) – Baconbeastnz

cevap

29

Sen this.getClass().getSuperClass() kullanabilirsiniz.

Yani, iyi kodunuzu çarpanlarına olurdu. Parametre olarak Field listesini alan ve mantıksal parçanızı gerçekleştiren bir yöntemi ve while(superClass != null) döngüsünü kullanarak alanları araştıran ana yöntemi uygulayın. Geç oldu rağmen güzel bir çözüm beri

+2

getFilds() yöntemini izleyin, benim durumumda süper sınıf için çalışmaz. Ben sadece getDeclaredFilds() ile başarılı oldum –

6

, benim önerim ekliyorum.

Bahar çerçeve org.springframework.util.ReflectionUtils bu sınıf kullanabileceğimiz çeşitli yöntemleri vardır güzel Util sınıf sağlarlar. objectClass ve superClasses öğelerinden bir öznitelik alan örneği elde etmek için ReflectionUtils.findField(clazz, fieldName);

kullanıyorum. İyi bir şey, bir istisna atmıyor olmasıdır. Bunun yerine, geçersiz olanlar için null değerini döndürür, böylece onu zarif bir şekilde halledebilirsiniz.

İlgili konular