"Lad os nu oprette og bruge et par annoteringer."

"Lad os for eksempel sige, at vi skriver en spilmotor. Vores spil har en masse karakterer, der falder i tre kategorier: elvere, paladsvagter og skurke."

"Efterhånden som spillet udvikles, kan der tilføjes nye karakterer, og dette vil ændre spillets balance. Derfor ville det være meget praktisk at tildele hver 'karakterklasse' sin egen annotering, der beskriver dens fysiske karakteristika."

"Hvis du gør det, ville det gøre det meget nemt at simulere kampe mellem forskellige karakterer og/eller hurtigt at beregne spilbalancen."

"Jeg er enig. Det er en god idé."

"Lad os skabe en @Person- annotation, der gemmer liv, styrke og magi samt angrebs- og forsvarsparametre. Sådan ser annotationen ud:"

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

"Og som et eksempel, her er, hvordan beskrivelsen af ​​en skov-elvermagiker ville se ud:"

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

"Og her er, hvordan beskrivelsen af ​​hovedskurken ville se ud:"

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

"Jeg kan se. Det minder mig lidt om markørgrænseflader."

"Ja. Bortset fra for det første behøver du ikke at arve noget. Og for det andet kan du gemme yderligere oplysninger i annoteringer."

"Der er et par flere annoteringer, der bruges til at markere annoteringer. Her er de: "

"@Retention-annotationen angiver, hvor vores annotering vil være synlig: kun i kildekoden, selv efter kompilering, eller endda under kørsel."

"@Target-annotationen angiver, hvad der specifikt kan markeres ved hjælp af annoteringen: klasser, felter, metoder, metodeparametre osv."

"Hvis vi ønsker, at vores annotering skal anvendes på klasser, der arver en annoteret klasse og ikke kun på selve den annoterede klasse, så skal vi annotere den med @Inherited."

"Sådan ville vores @Person. annotation se ud."

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

"Det var meget interessant, tak, Rishi."

Men hvordan arbejder man med disse annoteringer i programmet? Hvordan bruger du dem? Hvordan læser du deres værdier?"

"Dette gøres generelt ved hjælp af Reflection ."

"Sådan vil vi afgøre, hvilken karakter der er stærkest:"

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

"Her er de metoder, vi har brug for:"

Metoder Beskrivelse
isAnnotationPresent(Annotation.class)
Kontrollerer, om klassen har den angivne anmærkning
getAnnotation(Annotation.class)
Returnerer et anmærkningsobjekt, hvis klassen har den angivne anmærkning.
Annotation[] getAnnotations()
Returnerer en matrix af alle klassens annoteringer

"Fantastisk. Jeg havde ikke forventet at det ville være så enkelt at få en anmærkning."

"Uh huh." Kald blot objektets getAnnotation-metode og indtast den ønskede annotationstype."

"Det var det for i dag."

"Tak, Rishi. Dette var en meget interessant lektion. Nu frygter jeg ikke kommentarer, som jeg gør vand."