Java annotations are metadata (data about data) for our program source code.
They provide additional information about the program to the compiler but are not part of the program itself. These annotations do not affect the execution of the compiled program.
Annotations start with @
. Its syntax is:
Let’s take an example of @Override
annotation.
The @Override
annotation specifies that the method that has been marked with this annotation overrides the method of the superclass with the same method name, return type, and parameter list.
It is not mandatory to use @Override
when overriding a method. However, if we use it, the compiler gives an error if something is wrong (such as wrong parameter type) while overriding the method.
Ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Animal { public void displayInfo() { System.out.println("I am an animal."); } } class Dog extends Animal { @Override public void displayInfo() { System.out.println("I am a dog."); } } class Main { public static void main(String[] args) { Dog d1 = new Dog(); d1.displayInfo(); } } |
Output:
1 | I am a dog. |
Annotation formats
Annotations may also include elements (members/attributes/parameters).
Marker Annotations
Marker annotations do not contain members/elements. It is only used for marking a declaration.
Syntax:
1 | @Override |
Single element Annotations
A single element annotation contains only one element.
Syntax:
If there is only one element, it is a convention to name that element as value.
Multiple element Annotations
These annotations contain multiple elements separated by commas.
Syntax:
Annotation placement
Any declaration can be marked with annotation by placing it above that declaration. As of Java 8, annotations can also be placed before a type.
Above declarations
As mentioned above, Java annotations can be placed above class, method, interface, field, and other program element declarations.
Ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import java.util.*; class Main { @SuppressWarnings("unchecked") static void wordsList() { ArrayList wordList = new ArrayList<>(); // This causes an unchecked warning wordList.add("programiz"); System.out.println("Word list => " + wordList); } public static void main(String args[]) { wordsList(); } } |
Output:
1 | Word list => [programiz] |
Type annotations
Before Java 8, annotations could be applied to declarations only. Now, type annotations can be used as well. This means that we can place annotations wherever we use a type.
Constructor invocations
1 | new @Readonly ArrayList<>() |
Type definitions
1 | @NonNull String str; |
Type casts
1 | newStr = (@NonNull String) str; |
extends and implements clause
1 | class Warning extends @Localized Message |
throws clause
1 | public String readMethod() throws @Localized IOException |
Types of Annotations
Predefined annotations
- @Deprecated
- @Override
- @SuppressWarnings
- @SafeVarargs
- @FunctionalInterface
Meta-annotations
- @Retention
- @Documented
- @Target
- @Inherited
- @Repeatable
Custom annotations
It is also possible to create our own custom annotations.
Syntax:
Here is what you need to know about custom annotation:
- Annotations can be created by using
@interface
followed by the annotation name. - The annotation can have elements that look like methods but they do not have an implementation.
- The default value is optional. The parameters cannot have a null value.
- The return type of the method can be primitive, enum, string, class name or array of these types.
Ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @interface MyCustomAnnotation { String value() default "default value"; } class Main { @MyCustomAnnotation(value = "programiz") public void method1() { System.out.println("Test method 1"); } public static void main(String[] args) throws Exception { Main obj = new Main(); obj.method1(); } } |
Output:
1 | Test method 1 |
Use of Annotations
- Compiler instructions – Annotations can be used for giving instructions to the compiler, detect errors or suppress warnings. The built-in annotations
@Deprecated
,@Override
,@SuppressWarnings
are used for these purposes. - Compile-time instructions – Compile-time instructions provided by these annotations help the software build tools to generate code, XML files and many more.
- Runtime instructions – Some annotations can be defined to give instructions to the program at runtime. These annotations are accessed using Java Reflection.