2013-08-29 29 views
15

javadoc nói như sau:Sự khác nhau giữa Dòng # getAnnotations() và Field # getDeclaredAnnotations()

AccessibleObject#getDeclaredAnnotations:

Returns tất cả các chú thích liên quan trực tiếp có mặt trên yếu tố này. Không giống như các phương thức khác trong giao diện này, phương thức này bỏ qua các chú thích được kế thừa. (Trả về một mảng có độ dài bằng không nếu không có chú thích nào có mặt trực tiếp trên phần tử này.) Người gọi của phương thức này là miễn phí để sửa đổi mảng được trả về; nó sẽ không ảnh hưởng đến các mảng được trả lại cho những người gọi khác.

Field#getAnnotations:

Returns tất cả các chú thích có mặt trên yếu tố này. (Trả về một mảng có độ dài bằng không nếu phần tử này không có chú thích.) Người gọi của phương thức này là miễn phí để sửa đổi mảng được trả về; nó sẽ không ảnh hưởng đến các mảng được trả lại cho những người gọi khác.

Kể từ getAnnotations được kế thừa từ lớp java.lang.reflect.AccessibleObject, có Dòng đối tượng truy cập vào nó.

Vì tôi hiểu đó là sự khác biệt duy nhất giữa chúng getDeclaredAnnotations bỏ qua các chú thích được kế thừa. Tôi nhận được rằng khi giao dịch với các lớp học nhưng theo như tôi biết, các trường KHÔNG thể kế thừa các chú thích.

Trả lời

9

Nhìn vào mã nguồn cho câu trả lời:

đoạn trích từ java.lang.reflect.AccessibleObject:

/** 
* @since 1.5 
*/ 
public Annotation[] getAnnotations() { 
    return getDeclaredAnnotations(); 
} 

/** 
* @since 1.5 
*/ 
public Annotation[] getDeclaredAnnotations() { 
    throw new AssertionError("All subclasses should override this method"); 
} 

Và kể từ Field does not override getAnnotations(): getDeclaredAnnotations() được gọi.

Vì vậy, cả hai phương pháp đều thực hiện tương tự khi được gọi trên đối tượng java.lang.reflect.Field. (vì vậy javadoc là sai trong quan điểm của tôi)

trường hợp khác là java.lang.Class đó sẽ ghi đè cả hai phương pháp (và làm những gì nó JavaDoc nói;)):

/** 
* @since 1.5 
*/ 
public Annotation[] getAnnotations() { 
    initAnnotationsIfNecessary(); 
    return AnnotationParser.toArray(annotations); 
} 

/** 
* @since 1.5 
*/ 
public Annotation[] getDeclaredAnnotations() { 
    initAnnotationsIfNecessary(); 
    return AnnotationParser.toArray(declaredAnnotations); 
} 
-1

Điều ngược lại. getDeclaredAnnotations() - như tài liệu nói - là phương pháp duy nhất bỏ qua các chú thích được kế thừa.

Dưới đây là đoạn mà demostrates sự khác biệt:

public class Test1 { 
    public static void main(String[] args) { 
     Test3 test = new Test3(); 

     for (Annotation annotation : test.getClass().getAnnotations()) { 
      System.out.println("Class getAnnotations: " + annotation); 
     } 

     for (Annotation annotation : test.getClass().getDeclaredAnnotations()) { 
      System.out.println("Class getDeclaredAnnotations: " + annotation); 
     } 

     for (Field field : test.getClass().getFields()) { 
      for (Annotation annotation : field.getAnnotations()) { 
       System.out.println("Field getAnnotations: " + annotation); 
     } 

     for (Annotation annotation : field.getDeclaredAnnotations()) { 
      System.out.println("Field getDeclaredAnnotations: " + annotation); 
     } 
    } 
} 

@Retention(RetentionPolicy.RUNTIME) 
@Inherited 
@interface CustomAnnotation { 
    String value(); 
} 

@CustomAnnotation("Class") 
class Test2 { 
    @CustomAnnotation("Field") public String testString; 
} 

class Test3 extends Test2 {} 

Kết quả sẽ được `getAnnotations:

Class getAnnotations: @test.CustomAnnotation(value=Class) 
Field getAnnotations: @test.CustomAnnotation(value=Field) 
Field getDeclaredAnnotations: @test.CustomAnnotation(value=Field) 

Bạn thấy rằng Class getDeclaredAnnotations() là trống rỗng, vì lớp Test3 không có chú thích riêng của mình, chỉ những người thừa hưởng từ Test2.

Từ Javadoc cho @Inherited:

Chỉ ra rằng một loại chú thích được tự động di truyền. Nếu một chú thích meta được thừa kế có trong khai báo kiểu chú thích và người dùng truy vấn loại chú thích trên khai báo lớp và khai báo lớp không có chú thích cho loại này, thì lớp cha của lớp sẽ tự động được truy vấn cho loại chú thích. Quá trình này sẽ được lặp lại cho đến khi một chú thích cho loại này được tìm thấy, hoặc đạt đến đỉnh của phân cấp lớp (Object). Nếu không có siêu lớp nào có chú thích cho loại này, thì truy vấn sẽ cho biết rằng lớp đang được đề cập không có chú thích như vậy. Lưu ý rằng loại chú thích meta này không có hiệu lực nếu loại chú thích được sử dụng để chú thích bất kỳ thứ gì ngoài một lớp. Cũng lưu ý rằng meta-chú thích này chỉ gây ra các chú thích được thừa kế từ các siêu lớp; chú thích trên các giao diện được triển khai không có hiệu lực.

+1

Điều này áp dụng như thế nào với 'Field'? Ngoài ra OP tiểu bang _ Tôi nhận được rằng khi giao dịch với Classes_ –

+0

tôi biết làm thế nào nó hoạt động với Class nhưng tôi không nhận được trường. nhưng cảm ơn vì đã chỉ ra rằng tôi đã bỏ qua sai –

+0

cảm ơn vì đã cập nhật đoạn mã của bạn, nhưng tôi vẫn thấy không có sự khác biệt giữa các phương thức quá ... –

-1

getDeclaredAnnotations() cung cấp chú thích thực hiện trực tiếp chỉ khi getAnnotations() cung cấp các chú thích được triển khai trực tiếp cũng như các chú thích có thể kế thừa (@Inherited) từ lớp cha của nó.

Các vấn đề liên quan