"Ora creiamo e usiamo un paio di annotazioni."
"Ad esempio, supponiamo che stiamo scrivendo un motore di gioco. Il nostro gioco ha molti personaggi che rientrano in tre categorie: elfi, guardie del palazzo e cattivi."
"Man mano che il gioco viene sviluppato, potrebbero essere aggiunti nuovi personaggi e questo altererà l'equilibrio del gioco. Pertanto, sarebbe molto conveniente assegnare a ciascuna 'classe di personaggi' la propria annotazione che ne descriva le caratteristiche fisiche."
"In questo modo sarebbe molto facile simulare battaglie tra diversi personaggi e/o calcolare rapidamente il bilanciamento del gioco".
"Sono d'accordo. È una buona idea."
"Creiamo un'annotazione @Person che memorizzerà la vita, la forza e la magia, oltre ai parametri di attacco e difesa. Ecco come appare l'annotazione:"
@interface Person
{
String name() default "";
int live();
int strength();
int magic() default 0;
int attack() default 0;
int defense();
}
"E, come esempio, ecco come sarebbe la descrizione di un mago elfo della foresta:"
@Person(live = 100, strength = 10, magic = 5, attack = 20, defense = 20)
class Elf
{
…
}
"Ed ecco come apparirebbe la descrizione del cattivo principale:"
@Person(live = 1000, strength = 150, magic = 250, attack = 99, defense = 99)
class EvilMaster
{
…
}
"Capisco. Mi ricorda un po' le interfacce marker."
"Sì. Tranne che, primo, non devi ereditare nulla. E secondo, puoi memorizzare informazioni aggiuntive nelle annotazioni."
"Ci sono alcune altre annotazioni utilizzate per contrassegnare le annotazioni. Eccole: "
"L'annotazione @Retention indica dove sarà visibile la nostra annotazione: solo nel codice sorgente, anche dopo la compilazione o anche in fase di esecuzione."
"L'annotazione @Target indica cosa specificamente può essere contrassegnato utilizzando l'annotazione: classi, campi, metodi, parametri del metodo, ecc."
"Se vogliamo che la nostra annotazione venga applicata alle classi che ereditano una classe annotata e non solo alla classe annotata stessa, allora dobbiamo annotarla con @Inherited."
"Ecco come sarebbe la nostra annotazione @Person.. "
@Target(value = ElementType.TYPE) @Retention(value = RetentionPolicy.RUNTIME)
@interface Person
{
String name() default "";
int live();
int strength();
int magic() default 0;
int attack() default 0;
int defence();
}
"È stato molto interessante, grazie, Rishi."
Ma come lavori con queste annotazioni nel programma? Come li usate? Come leggi i loro valori?"
"Questo è generalmente fatto usando Reflection ."
"Ecco come determineremmo quale personaggio è più forte:"
public boolean fight(Class first, Class second)
{
if (!first.isAnnotationPresent(Person.class))
throw new RuntimeException("first param is not game person");
if (!second.isAnnotationPresent(Person.class))
throw new RuntimeException("second param is not game person");
Person firstPerson = (Person) first.getAnnotation(Person.class);
Person secondPerson = (Person) second.getAnnotation(Person.class);
int firstAttack = firstPerson.attack() * firstPerson.strength() + firstPerson.magic();
int firstPower = firstPerson.live() * firstPerson.defence() * firstAttack;
int secondAttack = secondPerson.attack() * secondPerson.strength() + secondPerson.magic();
int secondPower = secondPerson.live() * secondPerson.defence() * secondAttack;
return firstPower > secondPower;
}
"Ecco i metodi di cui abbiamo bisogno:"
Metodi | Descrizione |
---|---|
|
Controlla se la classe ha l'annotazione specificata |
|
Restituisce un oggetto annotazione se la classe ha l'annotazione specificata. |
|
Restituisce un array di tutte le annotazioni della classe |
"Fantastico. Non mi aspettavo che ricevere un'annotazione sarebbe stato così semplice."
"Uh Huh." Basta chiamare il metodo getAnnotation dell'oggetto, passando il tipo di annotazione desiderato."
"Questo è tutto per oggi."
"Grazie, Rishi. Questa è stata una lezione molto interessante. Ora non temo le annotazioni come faccio con l'acqua."
GO TO FULL VERSION