2013-08-29 6 views
15

JavaDoc dice quanto segue:Differenza tra campo # getAnnotations() e campo # getDeclaredAnnotations()

AccessibleObject#getDeclaredAnnotations:

Restituisce tutte le annotazioni che sono direttamente presenti su questo elemento. A differenza degli altri metodi in questa interfaccia, questo metodo ignora le annotazioni ereditate. (Restituisce un array di lunghezza zero se non ci sono annotazioni direttamente presenti su questo elemento.) Il chiamante di questo metodo è libero di modificare l'array restituito; non avrà alcun effetto sugli array restituiti ad altri chiamanti.

Field#getAnnotations:

restituisce tutte le annotazioni presenti su questo elemento. (Restituisce una matrice di lunghezza zero se questo elemento non ha annotazioni.) Il chiamante di questo metodo è libero di modificare l'array restituito; non avrà alcun effetto sugli array restituiti ad altri chiamanti.

Dal getAnnotations è ereditato dalla classe java.lang.reflect.AccessibleObject, avere gli oggetti campo accesso ad esso.

Come ho capito è l'unica differenza tra loro che getDeclaredAnnotations ignora annotazioni ereditate. L'ho capito quando mi occupo di Classi, ma per quanto ne so i Field NON possono ereditare annotazioni.

risposta

9

Guardando nel codice sorgente dà la risposta:

estratto da 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"); 
} 

E poiché Field does not override getAnnotations(): getDeclaredAnnotations() si chiama.

Quindi entrambi i metodi fanno lo stesso quando vengono richiamati su un oggetto java.lang.reflect.Field. (in modo che il JavaDoc è sbagliato a mio parere)

l'altro caso è java.lang.Class che sostituisce entrambi i metodi (e fa quello che sta JavaDoc dice;)):

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

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

È il contrario. getDeclaredAnnotations() - come dice il documento - è l'unico metodo che ignora le annotazioni ereditate.

Di seguito è frammento che demostrates la differenza:

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

L'uscita sarà `getAnnotations:

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

Si vede che il Class getDeclaredAnnotations() è vuoto, perché la classe Test3 non ha annotazioni per sé, solo quelli ereditati da Test2.

Dal Javadoc per @Inherited:

indica che un tipo di annotazione è ereditato automaticamente. Se una meta-annotazione ereditata è presente su una dichiarazione del tipo di annotazione e l'utente interroga il tipo di annotazione su una dichiarazione di classe e la dichiarazione della classe non ha annotazioni per questo tipo, la superclasse della classe verrà automaticamente interrogata per il tipo di annotazione. Questo processo verrà ripetuto fino a quando non viene trovata un'annotazione per questo tipo o viene raggiunta la parte superiore della gerarchia di classi (Object). Se nessuna superclasse ha un'annotazione per questo tipo, la query indicherà che la classe in questione non ha tale annotazione. Nota che questo tipo di meta-annotazione non ha effetto se il tipo annotato è usato per annotare qualcosa di diverso da una classe. Si noti inoltre che questa meta-annotazione fa sì che solo le annotazioni vengano ereditate dalle superclassi; le annotazioni sulle interfacce implementate non hanno alcun effetto.

+1

Come si applica a 'Field'? Anche OP afferma: "Ho capito che quando si ha a che fare con Classes_ –

+0

so come funziona con Class ma non ottengo campo. ma grazie per aver sottolineato che ho ignorato l'errore –

+0

grazie per aver aggiornato lo snippet, ma non vedo ancora differenze tra i metodi troppo ... –

-1

getDeclaredAnnotations() fornisce le annotazioni attuate diretti solo dove getAnnotations() fornisce annotazioni implementate dirette e ereditabili (@Inherited) dalla sua classe genitore.

Problemi correlati