"Låt oss nu skapa och använda ett par kommentarer."

"Till exempel, låt oss säga att vi skriver en spelmotor. Vårt spel har många karaktärer som delas in i tre kategorier: alver, palatsvakter och skurkar."

"När spelet utvecklas kan nya karaktärer läggas till, och detta kommer att förändra spelets balans. Därför skulle det vara mycket bekvämt att tilldela varje "karaktärsklass" sin egen annotering som beskriver dess fysiska egenskaper."

"Att göra det skulle göra det väldigt enkelt att simulera strider mellan olika karaktärer och/eller att snabbt beräkna spelbalansen."

"Jag håller med. Det är en bra idé."

"Låt oss skapa en @Person -kommentar som lagrar liv, styrka och magi, såväl som attack- och försvarsparametrar. Så här ser annoteringen ut:"

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

"Och som ett exempel, här är hur beskrivningen av en skogstomtemage skulle se ut:"

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

"Och så här skulle beskrivningen av huvudskurken se ut:"

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

"Jag förstår. Det påminner mig lite om markörgränssnitt."

"Ja. Förutom för det första behöver du inte ärva någonting. Och för det andra kan du lagra ytterligare information i kommentarer."

"Det finns några fler kommentarer som används för att markera kommentarer. Här är de: "

"@Retention-kommentaren indikerar var vår anteckning kommer att vara synlig: endast i källkoden, även efter kompilering, eller till och med under körning."

"@Target-kommentaren indikerar vad som specifikt kan markeras med anteckningen: klasser, fält, metoder, metodparametrar, etc."

"Om vi ​​vill att vår annotering ska tillämpas på klasser som ärver en kommenterad klass och inte bara på den kommenterade klassen, då måste vi annotera den med @Inherited."

"Så här skulle vår @Person. -anteckning se ut."

Exempel
@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 väldigt intressant, tack, Rishi."

Men hur arbetar man med dessa kommentarer i programmet? Hur använder du dem? Hur läser du deras värderingar?"

"Detta görs vanligtvis med Reflection ."

"Så här skulle vi avgöra vilken karaktär som är starkast:"

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

"Här är metoderna som vi behöver:"

Metoder Beskrivning
isAnnotationPresent(Annotation.class)
Kontrollerar om klassen har den angivna anteckningen
getAnnotation(Annotation.class)
Returnerar ett anteckningsobjekt om klassen har den angivna anteckningen.
Annotation[] getAnnotations()
Returnerar en uppsättning av alla klassens kommentarer

"Jättebra. Jag trodde inte att det skulle vara så enkelt att få en kommentar."

"Äh-ha." Anrop helt enkelt objektets getAnnotation-metod och skicka in önskad annoteringstyp."

"Det var allt för idag."

"Tack, Rishi. Det här var en mycket intressant lektion. Nu är jag inte rädd för kommentarer som jag gör vatten."