CodeGym /Java Course /Java Collections /How to create annotations

How to create annotations

Java Collections
Level 8 , Lesson 9
Available

"Now let's create and use a couple of annotations."

"For example, let's say we're writing a game engine. Our game has a lot of characters that fall into three categories: elves, palace guards, and villains."

"As the game is developed, new characters may be added, and this will alter the game balance. Thus, it would be very convenient to assign each 'character class' its own annotation that describes its physical characteristics."

"Doing so would make it very easy to simulate battles between different characters and/or quickly calculating the game balance."

"I agree. That's a good idea."

"Let's create a @Person annotation that will store life, strength, and magic, as well as attack and defense parameters. Here's how the annotation looks:"

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

"And, as an example, here's what the description of a forest elf mage would look like:"

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

"And here's how the description of the main villain would look:"

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

"I see. It reminds me a little of marker interfaces."

"Yes. Except, first, you don't have to inherit anything. And second, you can store additional information in annotations."

"There are a few more annotations used to mark annotations. Here they are:"

"The @Retention annotation indicates where our annotation will be visible: only in the source code, even after compilation, or even at run time."

"The @Target annotation indicates what specifically can be marked using the annotation: classes, fields, methods, method parameters, etc."

"If we want our annotation to be applied to classes that inherit an annotated class and not just to the annotated class itself, then we need to annotate it with @Inherited."

"This is what our @Person. annotation would look like."

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

"That was very interesting, thank you, Rishi."

But how do you work with these annotations in the program? How do you use them? How do you read their values?"

"This is generally done using Reflection."

"Here's how we would determine which character is stronger:"

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

"Here are the methods that we need:"

Methods Description
isAnnotationPresent(Annotation.class)
Checks whether the class has the specified annotation
getAnnotation(Annotation.class)
Returns an annotation object if the class has the specified annotation.
Annotation[] getAnnotations()
Returns an array of all of the class's annotations

"Great. I didn't expect getting an annotation would be so simple."

"Uh-huh." Simply call the object's getAnnotation method, passing in the desired annotation type."

"That's it for today."

"Thank you, Rishi. This was a very interesting lesson. Now I don't fear annotations like I do water."

Comments (2)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Justin Smith Level 41, Greenfield, USA, United States
20 February 2023
This interesting. I'm not really clear what would determine when you would use annotations vs simply having classes that inherit a common class. For the example given in the lesson, it seems that you could probably just create a Person class that the class Elf and the other two all inherit. And then using methods that they have in common wouldn't require the complicated reflection code to have two child classes interact. I'm not claiming that it's better to do it that way, only that I don't feel that I have a good understanding of why it isn't.
Andrei Level 41
27 July 2021
Interesting information about annotations. Nice!