2012-05-14 32 views
17

Gần đây tôi đã thay đổi lược đồ của mình một chút để lớp của tôi kế thừa từ một lớp siêu, vấn đề là phương pháp so sánh của tôi tạo nhật ký kiểm tra, sử dụng phản chiếu Java, hiện chỉ lặp qua các trường của con lớp học, không phải là siêu lớp, có cách nào để có được tất cả các FIELDS không? hoặc tôi có cần bỏ nó vào lớp siêu đẳng .....?Làm thế nào để Java phản ánh các trường tại chỗ trong lớp siêu? không chỉ là lớp thực tế

Heres phương pháp của tôi dưới đây:

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: Có lẽ bạn không nên đặt 'field.setAccessible (false)' để ngăn điều kiện cuộc đua trong môi trường nhiều luồng ... –

+1

phương tiện của bạn là: 'instance.getClass(). GetSuperCLass(). GetDeclaredFields() '? – MJM

+0

Cảm ơn MJM, cảm ơn tất cả mọi người, yip đã làm nó dễ dàng như chiếc bánh! :) – Baconbeastnz

Trả lời

29

Bạn có thể sử dụng cho đến khi this.getClass().getSuperClass() phương pháp getSuperClass() này trả về null để có được những lĩnh vực mẹ.

Vì vậy, tốt nhất là bạn nên xác định mã của mình. Thực hiện một phương thức lấy danh sách Field làm tham số và thực hiện phần logic của bạn bên trong nó, và một phương thức chính tìm kiếm các trường thông qua một vòng lặp while(superClass != null).

+2

xem cho phương thức getFilds(), trong trường hợp của tôi nó không hoạt động cho lớp cha. Tôi chỉ thành công với getDeclaredFilds() –

6

Mặc dù đã trễ, tôi đang thêm đề xuất của mình vì đây là một giải pháp tốt.

Khung công tác Spring cung cấp lớp Util đẹp org.springframework.util.ReflectionUtils lớp này có một số phương pháp mà chúng tôi có thể sử dụng. Để có được một thể hiện trường của một thuộc tính từ objectClass và superClasses tôi đã sử dụng ReflectionUtils.findField(clazz, fieldName);

Điều tốt với util là nó không ném một ngoại lệ. Thay vào đó nó trả về null cho những cái không hợp lệ, vì vậy bạn có thể xử lý nó một cách duyên dáng.