In Java, annotations are kind of metadata which provide data about a program. They mark classes, methods, fields, variables and other elements of a program.
Annotations can be used for different purposes:
information for the compiler;
information for developing tools to generate code, XML files and so forth;
information for frameworks and libraries at runtime.
Marking elements with annotations
To mark an element (class/method/field/etc) by an annotation we need to write the symbol @ followed by the annotation name, for example:
@Deprecated
The symbol @ signals to the compiler that this is an annotation.
Tab 1 content
Tab 2 content
Tab 3 content
Build-in annotations
Java has three built-in general-purposes annotations:
@Deprecated - indicates that the marked element (class, method, field and so one) is deprecated and should no longer be used. Causes a compile warning if the element is used.
@SuppressWarnings - instructs the compiler to suppress the compile-time warnings specified in the annotation parameters. The annotation can be applied to classes, methods, fields, local variables and not only.
@Override - it is used above a method that overrides a method in a superclass. Causes a compile error if the method is not found in one of the parent classes or implemented interfaces. The annotation can be applied only to methods.
Let's annotate a method just for example:
@Deprecated
public static void method() {
System.out.println("an old method");
}
It means method should not be used.
You can deprecate even a whole class:
@Deprecated
class MyClass {
// fields and methods
}
It's possible to mark a class/method/field/etc by two or more annotations.
Annotation elements
Some annotation includes some elements. Elements have a type. For example, the annotation @SupressWarnings has an element named value to specify what type of warning we'd like to suppress.
@SuppressWarnings(value = "unused")
public static void method() {
int a = 0;
}
Now, you should remember only two possible values: "unused" and "deprecation". The first instructs the compiler to suppress warnings about unused local variables, the second - instructs to suppress warnings about using deprecated fields/methods/classes/etc.
If there is just one element named value, then the name can be omitted (unnamed element):
@SuppressWarnings("unused")
public static void method() {
int a = 0;
}
An annotation element can be an array (value is an array):
@SuppressWarnings({"unused", "deprecation"})
public static void method() { ... }
This way is correct because the single element of @SuppressWarnings is an array.
If an element of an annotation has a default value, it may be skipped. The element value of @SuppressWarnings has no default element, therefore it cannot be skipped. The following syntax is not correct:
@SuppressWarnings // it's not a correct syntax for this annotation
public static void method() { ... }
A custom annotation example
We won't write any new annotations in this topic. Let's assume, we have an external library that includes two annotations @NotNull and @Range. Both annotations marks classes, fields, methods and parameters.
The @NotNull indicates that:
a method should not return null;
a variable cannot be null.
The @Range indicates that
a method returns an integer number that belongs to the specified range;
a variable always belongs to the specified range.
To demonstrate these annotations here is a class that represents a computer game character.
class GameCharacter {
@NotNull
private String login;
@Range(min = 1, max = 100)
private int level = 1;
public GameCharacter(
@NotNull String login,
@Range(min = 1, max = 100) int level) {
this.login = login;
this.level = level;
}
@NotNull
public String getLogin() {
return login;
}
@Range(min = 1, max = 100)
public int getLevel() {
return level;
}
}
These annotations may be used by a static code analyzer to check your code and show some warnings.
Of course, the provided class and annotations are just an example. But in large applications, classes and their members may have a lot of annotations.
Note: the annotation @NotNull is taken from here: https://www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html. The annotation @Range is written as just an example, but some frameworks and libraries have an annotation with the same name but a slightly different meaning.