Adding Annotations in Java
Java annotation is a special instrument that provides information about a program. Its main goal is to make programmers' lives easier. To give a more formal definition, annotations are a form of metadata, which means they are not part of the program itself.
You can mark classes, methods, fields, variables, and other parts of a program with annotations. When you do it, those meta annotations in the source code provide information for the compiler, for some development tools, or for frameworks and libraries at runtime.
Now that you know how useful they are, you have no other choice but to make friends with Java annotations!
Annotation, where are you?
But do you understand that the day has come, and what is in front of you is your first annotation? All annotations start with the @
symbol followed by the annotation name, and they are usually highlighted with a color different from the usual code.
Here is an example:
@Override
public void printName() {
System.out.println(this.name);
}
@Override
is an annotation here.
You can also mark a class/method/field/etc. with two or more annotations!
Built-in annotations
Java has several built-in annotations. If you want to use other annotations, you will need to include libraries or frameworks or even create your own annotations.
But first, let's discuss the three main built-in annotation types that were presented to the world in Java 5:
@Deprecated
is a simple annotation which means that the marked method (or class, field, and so on) is deprecated, that is, obsolete and should no longer be used. This annotation causes a compiler warning if the code is used.
@Deprecated
public void oldMethod() {
System.out.println("Hello!");
}
@SuppressWarnings
commands the compiler to disable some warnings at compile time. You specify in parameters which warnings you don't want to see. Here is a code example:
@SuppressWarnings("unused")
public void printHello() {
System.out.println("Hello!");
}
Imagine you created a method printHello
but didn't use it. The compiler doesn't like such unused methods so it gives a warning that the method is not used. With the help of @SuppressWarnings("unused")
annotation where "unused" is a parameter, you can disable that compile warning. This annotation can be applied to classes, methods, fields, local variables, and other parts of the program.
@Override
marks a method that overrides a superclass (or parent class) method. This annotation can only be applied to methods. We will consider it in detail in a separate topic about overriding methods.
Annotation elements
Some annotations have elements, where an element is similar to an attribute or a parameter. Let's give it a closer look.
Remember the annotation called @SuppressWarnings
? It takes the type of warning you want to disable as a parameter.
@SuppressWarnings("unused")
public void printHello() {
System.out.println("Hello!");
}
If you entertain some curiosity and look inside the @SuppressWarnings
annotation, you will find out that it has only one element named value
. Because the element is just one and is called value
, it can be omitted. But the full definition will look like this:
@SuppressWarnings(value = "unused")
public void printHello() {
System.out.println("Hello!");
}
Pay attention that the full definition could be omitted for a field named "value" only. For other field names, the full definition is required.
An annotation element can also be an array. In fact, the actual type of value
in @SuppressWarnings
annotation is String[]
:
@SuppressWarnings({"unused", "deprecation"})
public void printHello() { ... }
"deprecation"
, as you might have guessed from the name, instructs the compiler to suppress warnings about the use of deprecated code.
Finally, the last thing you need to know is that some annotations have a default value for an element, and some don't.
@SuppressWarnings // wrong syntax, there is no default value!
public void printHello() {
System.out.println("Hello!");
}
For example, @SuppressWarnings
doesn't have a default value, so you can't skip it.
The @Deprecated annotation
For many years the @Deprecated
annotation didn't have any elements, but starting from Java 9 it has two: since
and forRemoval
. We will quickly break them down because there is a big chance you will meet them in practice.
since
requires the version (a String value) in which the annotated element has become deprecated. The default value is an empty string.forRemoval
indicates whether the annotated element is to be removed in a future version. The default value isfalse
.
@Deprecated(since = "5.3", forRemoval = true)
public void printHello() {
System.out.println("Hello!");
}
The example above means that the printHello
method has been deprecated since version 5.3 of our library and it will be removed in the next release.
Wow, a custom annotation
Fear not: we won't create any new annotations in this topic. But we will look into two common annotations from external sources.
Both the @NotNull
and @Range
annotations mark classes, fields, methods, and parameters.
The @NotNull
annotation indicates either of the following two options:
- a variable cannot be
null
; - a method should not return
null
.
And the @Range
annotation indicates either of the following options:
- a variable always belongs to the specified range;
- a method returns an integer number that belongs to the specified range.
Now let's look at our class called GameCharacter
:
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;
}
}
Here, these annotations will help you by showing warnings if login
contains null
, or if the level
of your character is less than 1 or more than 100.
@NotNull
is taken from JetBrains and @Range
is taken from the popular framework – Hibernate.
Conclusion
In this topic, you finally covered the basics of annotations, and now you know that their main goal is to provide some important information to the compiler, development tools, frameworks, and libraries at runtime. Some annotations contain elements for which you can provide values. You also learned about the three built-in annotations and looked at a couple of examples of custom annotations.
In real-life programming, you will meet plenty of different annotations, but there is no reason to be afraid: they are here to make your life easier, improve code readability, and you can always find some tutorials and explanations you need in documentation.