"Laten we nu een paar annotaties maken en gebruiken."
"Laten we bijvoorbeeld zeggen dat we een game-engine schrijven. Onze game heeft veel personages die in drie categorieën vallen: elven, paleiswachten en schurken."
"Naarmate het spel wordt ontwikkeld, kunnen nieuwe personages worden toegevoegd, en dit zal de spelbalans veranderen. Het zou dus erg handig zijn om elke 'karakterklasse' zijn eigen annotatie toe te wijzen die de fysieke kenmerken beschrijft."
"Dit zou het heel gemakkelijk maken om gevechten tussen verschillende personages te simuleren en/of snel de spelbalans te berekenen."
'Ik ben het ermee eens. Dat is een goed idee.'
"Laten we een @Person- annotatie maken waarin leven, kracht en magie worden opgeslagen, evenals aanvals- en verdedigingsparameters. Zo ziet de annotatie eruit:"
@interface Person
{
String name() default "";
int live();
int strength();
int magic() default 0;
int attack() default 0;
int defense();
}
"En, als voorbeeld, hier is hoe de beschrijving van een boself-magiër eruit zou zien:"
@Person(live = 100, strength = 10, magic = 5, attack = 20, defense = 20)
class Elf
{
…
}
"En zo zou de beschrijving van de hoofdschurk eruit zien:"
@Person(live = 1000, strength = 150, magic = 250, attack = 99, defense = 99)
class EvilMaster
{
…
}
"Ik snap het. Het doet me een beetje denken aan marker-interfaces."
'Ja. Behalve dat je ten eerste niets hoeft te erven. En ten tweede kun je aanvullende informatie opslaan in annotaties.'
"Er zijn nog een paar annotaties die worden gebruikt om annotaties te markeren. Hier zijn ze: "
"De @Retention-annotatie geeft aan waar onze annotatie zichtbaar zal zijn: alleen in de broncode, zelfs na compilatie of zelfs tijdens runtime."
"De @Target-annotatie geeft aan wat specifiek kan worden gemarkeerd met behulp van de annotatie: klassen, velden, methoden, methodeparameters, enz."
"Als we willen dat onze annotatie wordt toegepast op klassen die een geannoteerde klasse erven en niet alleen op de geannoteerde klasse zelf, dan moeten we deze annoteren met @Inherited."
"Dit is hoe onze @Person.- annotatie eruit zou zien."
@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();
}
"Dat was heel interessant, dank je, Rishi."
Maar hoe werk je met deze annotaties in het programma? Hoe gebruik je ze? Hoe lees je hun waarden?"
"Dit wordt over het algemeen gedaan met Reflection ."
"Hier is hoe we zouden bepalen welk personage sterker is:"
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;
}
"Hier zijn de methoden die we nodig hebben:"
methoden | Beschrijving |
---|---|
|
Controleert of de klasse de opgegeven annotatie heeft |
|
Retourneert een annotatieobject als de klasse de opgegeven annotatie heeft. |
|
Retourneert een array van alle annotaties van de klasse |
"Geweldig. Ik had niet verwacht dat het zo eenvoudig zou zijn om een annotatie te krijgen."
"Uh Huh." Roep gewoon de getAnnotation-methode van het object aan en geef het gewenste annotatietype door."
"Dat is het voor vandaag."
"Dank je, Rishi. Dit was een heel interessante les. Nu ben ik niet bang voor annotaties zoals voor water."
GO TO FULL VERSION