2013-08-29 2 views
15

JavaDoc говорит следующее:разница между полем # getAnnotations() и поле # getDeclaredAnnotations()

AccessibleObject#getDeclaredAnnotations:

Возвращает все аннотации, которые непосредственно присутствуют на этом элементе. В отличие от других методов в этом интерфейсе, этот метод игнорирует унаследованные аннотации. (Возвращает массив нулевой длины, если в этом элементе не присутствуют аннотации.) Вызывающий этого метода может свободно изменять возвращенный массив; это не повлияет на массивы, возвращенные другим абонентам.

Field#getAnnotations:

Возвращает все аннотации, представленные на этом элементе. (Возвращает массив нулевой длины, если этот элемент не имеет аннотаций.) Вызывающий этого метода может свободно изменять возвращенный массив; это не повлияет на массивы, возвращенные другим абонентам.

С getAnnotations унаследован от класса java.lang.reflect.AccessibleObject, имеют к нему объекты Field.

Как я понимаю, это единственная разница между ними, что getDeclaredAnnotations игнорирует унаследованные аннотации. Я получаю это при работе с классами, но насколько я знаю, поля не могут наследовать аннотации.

ответ

9

Глядя в исходном коде дает ответ:

отрывок из 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"); 
} 

И так Field does not override getAnnotations(): getDeclaredAnnotations() называется.

Таким образом, оба метода делают то же самое при вызове объекта java.lang.reflect.Field. (так JavaDoc неправильно, на мой взгляд)

другой случай java.lang.Class который перекрывает оба метода (и делает то, что он JavaDoc говорит;)):

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

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

Это наоборот. getDeclaredAnnotations() - как говорится в документах - это единственный метод, который игнорирует унаследованные аннотации.

Ниже фрагмент кода, который demostrates разницу:

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 {} 

Выход будет `getAnnotations:

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

Вы видите, что Class getDeclaredAnnotations() пуст, потому что класс Test3 не примечаниями себя, только унаследованные от Test2.

Из Javadoc для @Inherited:

Указывает, что тип аннотации автоматически передается по наследству. Если в объявлении типа аннотации присутствует унаследованная мета-аннотация, и пользователь запрашивает тип аннотации в объявлении класса, а объявление класса не имеет аннотации для этого типа, тогда суперкласс класса будет автоматически запрашиваться для типа аннотации. Этот процесс будет повторяться до тех пор, пока не будет найдена аннотация для этого типа или не будет достигнута вершина иерархии классов (объект). Если у суперкласса нет аннотации для этого типа, тогда запрос будет указывать, что этот класс не имеет такой аннотации. Обратите внимание, что этот тип мета-аннотации не действует, если аннотированный тип используется для аннотации чего-либо, кроме класса. Обратите внимание также, что эта мета-аннотация позволяет только унаследовать аннотации от суперклассов; аннотации на реализованные интерфейсы не влияют.

+1

Как это относится к «Поле»? Также OP-состояния _I получают это при работе с Classes_ –

+0

Я знаю, как это работает с классом, но я не получаю поле. , но спасибо за указание, что я получил игнорирование неправильного –

+0

спасибо за обновление вашего фрагмента, но по-прежнему не вижу разницы между слишком методами ... –

-1

getDeclaredAnnotations() обеспечивает прямые реализованные аннотаций только в том случае, когда getAnnotations() предоставляет прямые реализации, а также наследуемые аннотации (@Inherited) из своего родительского класса.