"Ahora vamos a crear y usar un par de anotaciones".

"Por ejemplo, digamos que estamos escribiendo un motor de juego. Nuestro juego tiene muchos personajes que se dividen en tres categorías: elfos, guardias de palacio y villanos".

"A medida que se desarrolla el juego, se pueden agregar nuevos personajes, y esto alterará el equilibrio del juego. Por lo tanto, sería muy conveniente asignar a cada 'clase de personaje' su propia anotación que describa sus características físicas".

"Hacerlo haría muy fácil simular batallas entre diferentes personajes y/o calcular rápidamente el equilibrio del juego".

"Estoy de acuerdo. Es una buena idea".

"Creemos una anotación @Person que almacenará la vida, la fuerza y ​​la magia, así como los parámetros de ataque y defensa. Así es como se ve la anotación:"

Ejemplo
@interface Person
{
 String name() default "";
 int live();
 int strength();
 int magic() default 0;
 int attack() default 0;
 int defense();
}

"Y, como ejemplo, así es como se vería la descripción de un mago elfo del bosque:"

Ejemplo
@Person(live = 100, strength = 10, magic = 5, attack = 20, defense = 20)
class Elf
{
 …
}

"Y así es como se vería la descripción del villano principal:"

Ejemplo
@Person(live = 1000, strength = 150, magic = 250, attack = 99, defense = 99)
class EvilMaster
{
 …
}

"Ya veo. Me recuerda un poco a las interfaces de marcadores".

"Sí. Excepto que, primero, no tienes que heredar nada. Y segundo, puedes almacenar información adicional en anotaciones".

"Hay algunas anotaciones más que se usan para marcar anotaciones. Aquí están: "

"La anotación @Retention indica dónde estará visible nuestra anotación: solo en el código fuente, incluso después de la compilación o incluso en tiempo de ejecución".

"La anotación @Target indica qué se puede marcar específicamente usando la anotación: clases, campos, métodos, parámetros de métodos, etc."

"Si queremos que nuestra anotación se aplique a las clases que heredan una clase anotada y no solo a la clase anotada en sí, entonces debemos anotarla con @Inherited".

"Así es como se vería nuestra anotación @Person. ".

Ejemplo
@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();
}

"Eso fue muy interesante, gracias, Rishi".

Pero, ¿cómo trabajas con estas anotaciones en el programa? ¿Cómo los usas? ¿Cómo lees sus valores?"

"Esto generalmente se hace usando Reflection ".

"Así es como determinaríamos qué personaje es más fuerte:"

Ejemplo
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;
}

"Estos son los métodos que necesitamos:"

Métodos Descripción
isAnnotationPresent(Annotation.class)
Comprueba si la clase tiene la anotación especificada
getAnnotation(Annotation.class)
Devuelve un objeto de anotación si la clase tiene la anotación especificada.
Annotation[] getAnnotations()
Devuelve una matriz de todas las anotaciones de la clase.

"Genial. No esperaba que obtener una anotación fuera tan simple".

"UH Huh." Simplemente llame al método getAnnotation del objeto, pasando el tipo de anotación deseado".

"Es todo por hoy."

"Gracias, Rishi. Esta fue una lección muy interesante. Ahora no le temo a las anotaciones como al agua".