2011-10-09 19 views
9

Sono ancora abbastanza nuovo per la programmazione Java e che stavo cercando nel corso di un progetto open source e sono imbattuto in questoCome funzionano le annotazioni dell'utente?

public @TileNetworkData int progressPart = 0; 

ho visto l'uso di @ prima, ma solo per fare le cose come @override prima che un membro. Con mia grande sorpresa alzando la definizione che mi ha portato a codice utente

import java.lang.annotation.Inherited; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
@Inherited 
public @interface TileNetworkData { 

    int staticSize() default -1; 

} 

Che cosa sta facendo questo codice, e ciò che è utile per? Sembra che aggiunga qualche forma di metadati al campo. Come si usa qualcosa del genere?

Facendo un po 'di Google, ho scoperto che questo si chiama "Annotazioni", ma tutto ciò che vi era allegato mi passò per la testa. Qualsiasi tipo di esempio in cui qualcosa di simile sarebbe usato sarebbe apprezzato.

risposta

5

Annotations vengono utilizzati come "metadati leggibili dalla macchina" - descrivono i campi, i metodi e le classi che etichettano in modo che il compilatore e il runtime possano analizzare e possibilmente comprendere. Se hai familiarità con .NET's attributes, troverai che le annotazioni Java sono usate allo stesso modo.

Ad esempio, l'annotazione TileNetworkData definita nell'esempio è decorata con un'annotazione Retention(RetentionPolicy.RUNTIME). Questo dice al compilatore di incorporare l'annotazione TileNetworkData nel bytecode per i campi che annota. La stessa annotazione indica anche al runtime Java che, quando carica le classi con i campi con annotazioni TileNetworkData, deve mantenere l'annotazione TileNetworkData per il riflesso di runtime.

Ora, il codice può riflettere su campi di un oggetto per trovare le annotazioni TileNetworkData e fare qualcosa con campi in modo annotati:

// I haven't even compiled this code, and even if it works, it's still insane. 
// (others who know annotations better should feel free to edit or replace) 
public void copyTileNetworkDataToCache (Object data, Cache<?> cache) { 
    for (Field f : data.getClass().getFields()) { 
    if (f.isAnnotationPresent(TileNetworkData.class)) { 
     cache.save(f.get(data)); 
    } 
    } 
} 

si può anche scrivere il codice che insegna il compilatore Java how to interpret your annotations at compile time, utilizzando il apt front-end negli switch JDK 5 e javac in JDK 6 e versioni successive. Per creare un altro esempio di lame, l'accesso alla rete di riquadri potrebbe richiedere così tanto tempo che si desidera evitare di utilizzare i dati da esso ogni volta che è possibile. Quindi, potresti voler creare un elenco di tutte le classi che includono i campi con annotazioni TileNetworkData, in modo da poterle rivedere tutte e possibilmente riscrivere quelle che non hanno assolutamente bisogno di accedere alla rete di tile. Per fare ciò, è possibile scrivere un processore di annotazione che stampi tutte le classi corrispondenti, quindi indirizzare il punto apt al processore durante la compilazione.

2

Le annotazioni vengono utilizzate per metadati, per descrivere metodi, classi e altri tipi di oggetto.

È possibile utilizzare il per assegnare metadati (descrizioni dei dati) alle classi java. L'esempio classico è @Deprecated, che contrassegna un metodo come "da non utilizzare in futuro".

Ad esempio, è possibile utilizzarli per aggiungere informazioni di configurazione a una classe java. Se si sta utilizzando Hibernate (un ORM), si aggiungono annotazioni alla classe che indicano che questa classe deve essere compilata dalle informazioni contenute nella tabella del database table_xxx e che le informazioni della colonna column_xxx devono essere memorizzate in tale campo nella classe.

Il codice che hai postato sta definendo l'annotazione. Ciò consentirà che questa annotazione venga utilizzata altrove nel codice. Sta dicendo che l'annotazione sarà disponibile in runtime, @Retention(RetentionPolicy.RUNTIME), e che l'annotazione dovrebbe essere disponibile sia per la classe che lo utilizza sia per le sottoclassi di quella classe.

Per ulteriori informazioni, vedere le risposte a How and where are Annotations used in Java?

+0

Questo non corrisponde esattamente a ciò che l'OP chiede in modo specifico. – BoltClock

1

I metadati possono essere interrogati attraverso la riflessione. Pertanto, se nel codice è presente un codice generico void submitTileNetworkData(Object model), esso può iterare sui campi di model e creare un dump binario basato su annotazioni TileNetworkData.

4

Esempio: transazione di demarcazione:

public class TransactionalThing { 
    @Transactional 
    public void doSomePersistenceStuff() { 
     Foo foo = loadAFoo(); 
     doSomeStuffWith(foo); 
     foo.setProcessed(true); 
    } 
} 

Non ci sarebbe altro codice che cerca metodi annotati da @Transactional, avvia una transazione prima che il metodo viene chiamato, e si impegna (o rollback) della transazione quando finisce . È inoltre possibile inserire le informazioni nel annotazione di cose come, ad esempio, le regole di rollback:

@Transactional(rollbackFor = SomeException.class, 
       noRollbackFor = SomeOtherException.class) 

E ancora, è solo fino al codice che esegue la scansione queste transazioni da leggere in quegli attributi e gestire le cose in modo appropriato.

Problemi correlati