Annotations in Java – Types, Examples and Uses
In our last tutorial, we studied Java Assertion in detail. In this Java Annotations tutorial, we will learn Java Annotation, how to apply them, and a list of annotations in Java Programming Language.
For example, Marker, Single Value, and Full Java Annotations. We will also discuss Standard Java Annotations or built-in annotations in Java. We will discuss some Java annotation examples.
What is a Java Annotation?
Java Annotation is a kind of a tag that represents the metadata or information attached with class, interface, methods, or fields to show some additional information that Java compiler and JVM can use.
Though Annotations are not a part of the Java code they allow us to add metadata information into our source code. Java introduced Annotations from JDK 5.
There is no direct effect of Annotations on the operation of the code they annotate; they do not affect the execution of the program. Annotations provide supplemental information about a program.
Some points about Annotations are:
- They start with ‘@’.
- They do not change the action or execution of a compiled program.
- Annotations help to associate metadata or information to the elements of the program like classes, instance variables, interfaces, constructors, methods, etc.
- We cannot consider Annotations as pure comments as they can change the way a compiler treats a program
Example of Java Annotation
class Base { public void display() { System.out.println("Base class display() method"); } } public class Derived extends Base {@Override public void display(int x) { System.out.println("Derived class display(int) method"); } public static void main(String args[]) { Derived obj = new Derived(); obj.display(); } }
Output:
error: method does not override or implement a method from a supertype
@Override
If we remove parameter (int x) from the method or if we remove the @override annotation from the code, then the program compiles fine. The output will be:
Base class display() method
Types of Java Annotations
There are five types of Java Annotations which are:
- Marker Annotations
- Single Value Annotations
- Full Annotations
- Type Annotation
- Repeating Annotation
1. Marker Annotations
The only purpose of the Marker Annotation is to mark a declaration. The Marker Annotations do not contain any members and do not consist of any data.
Therefore, the presence of these annotations as an annotation is sufficient. Since the marker interface in java contains no members, simply determining whether it is present or absent is sufficient. @Override is an example of Marker Annotation.
Example: – @TestAnnotation()
2. Single value Annotations
The Single Value Annotations as the name suggests, contain only one member. They allow a shorthand form of specifying the value of the member.
When we apply this annotation, we only need to specify the value for that member and also do not need to specify the name of the member. However, in order to use this shorthand, there must be a value for the name of the member.
Example: @TestAnnotation(“testing”);
3. Full Annotations
The full Annotations consist of multiple data members/names, values, and pairs.
Example:- @TestAnnotation(owner= ”Rahul”, value= ”Class DataFlair”)
4. Type Annotations in Java
The type annotations are applicable to any place where there is a use of a type. For example, if we want to annotate the return type of a method, we can declare these annotations with @Target annotation.
Code to demonstrate a Type Annotation
import java.lang.annotation. * ;@Target(ElementType.TYPE_USE)@interface TypeAnnoDemo {} public class MyClass { public static void main(String[] args) {@TypeAnnoDemo String s = "Hello,I am annotated with a type annotation"; System.out.println(s); myMethod(); } static@TypeAnnoDemo int myMethod() { System.out.println("There is a use of annotation with the return type of the function”); return 0; } }
Output:
I am annotated with a type annotation
There is a use of annotation with the return type of the function”);
5. Repeating Annotations in java
Repeating Annotations are the annotations that we apply to a single item more than once. The repeating annotations must be annotated with the @Repeatable annotation, which is present in the java.lang.annotation package. The value of this annotation specifies the container type for the repeatable annotation.
There is a container specified as an annotation whose value field is an array of the repeatable annotation type. Hence, to create a repeatable annotation, firstly we need to create the container annotation, and then specify the annotation type as an argument to the @Repeatable annotation.
Code to demonstrate a repeatable annotation
import java.lang. * ;@Retention(RetentionPolicy.RUNTIME)@Repeatable(MyRepeatedAnnos.class)@interface MyWords { String word() default "Hello World"; int value() default 0; } // Creating a container annotation @Retention(RetentionPolicy.RUNTIME)@interface MyRepeatedAnnotations { MyWords[] value(); } public class MyClass { @MyWords(word = "Data", value = 1)@MyWords(word = "Flair", value = 2) public static void myMethod() { MyClass obj = new MyClass(); try { Class < ?>c = obj.getClass(); Method m = c.getMethod("myMethod"); Annotation a = m.getAnnotation(MyRepeatedAnnotations.class); System.out.println(anno); } catch(NoSuchMethodException e) { System.out.println(e); } } public static void main(String[] args) { myMethod(); } }
Output:
@MyRepeatedAnnotations(value={@MyWords(value=1, word=”Data”), @Words(value=2, word=”Flair”)})
Predefined/ Standard Annotations in java
Java has six built-in annotations as follows:
1) @Override
We should use @Override annotation while overriding a method in the child class to mark that method.
This provides more readability to the code and avoids maintenance issues like you must change the signature in child classes (where we are using this annotation) while changing the method signature of the parent class otherwise, the compiler would throw compilation error.
This is difficult to trace when you do not have used this annotation.
Example:
class ParentClass { public void display() { System.out.println("Parent class display() method"); } public static void main(String args[]) { ParentClass obj = new ChildClass); obj.display(); } } class ChildClass extends ParentClass {@Override public void display() { System.out.println("Child class display() method"); } }
Output:
Child class display() method
2) @Deprecated
The @Deprecated annotation indicates that a marked class, method, or field is ‘deprecated’ and they are no longer in use. The compiler gives a warning message whenever there is a use of deprecated class, method, or field marked with the @Deprecated annotation in the program.
When an element is deprecated, there is a need to document them using the Javadoc @deprecated tag. You should note that there is a difference between @Deprecated and @deprecated. @deprecated is for documentation purposes, and @Deprecated is for Annotations.
Example:
public class Test {@Deprecated public void display() { System.out.println("display() method of Test class"); } public static void main(String args[]) { Test obj = new DeprecatedTest(); obj.display(); } }
Output:
display() method of Test class
3) @SuppressWarnings
The @SupressWarnings annotation instructs the compiler to ignore specific warnings.
For example in the below code, We are calling a deprecated method so the compiler should generate a warning, however, we are using @SuppressWarnings annotation that would suppress that deprecation warning.
Example:
class Test {@Deprecated public void display() { System.out.println("display() method of Test class"); } } public class SuppressWarningTest {@SuppressWarnings({ "checked", "deprecation" }) public static void main(String args[]) { DeprecatedTest obj = new DeprecatedTest(); obj1.display(); } }
Output:
display() method of Test class
4) @Documented Annotations in Java
The @Documented Annotation is a annotation that says a tool that there is a need for documenting an annotation. Annotations are not present in Javadoc comments.
The @Documented annotation enables tools like Javadoc to process it and include the annotation type information in the generated document.
5) @Target
The design of Target annotation is such that we can use them only as an annotation to another annotation. @Target Annotation takes one argument and this argument must be a constant value from the ElementType enumeration.
The following table shows the constants along with the type of the declaration to which they correspond.
Target Constant | Annotations applied to |
ANNOTATION_TYPE | Another annotation |
CONSTRUCTOR | Constructor |
FIELD | Field |
LOCAL_VARIABLE | Local variable |
METHOD | Method |
PACKAGE | Package |
PARAMETER | Parameter |
TYPE | Class, Interface, or enumeration |
6) @Inherited
@Inherited is a marker annotation that we can use only on the annotation declaration. It affects only annotations used on class declarations. @Inherited annotation causes the subclass to inherit the annotation for a superclass.
Therefore, whenever there is a request to a subclass for a specific annotation, and if the annotation is absent in the subclass, then it checks its superclass. If that annotation is present in the superclass, and if it is annotated with @Inherited, then it returns that annotation.
What’s the use of Java Annotations?
1. Instructions to the compiler
We can use the built-in annotation in Java to give instructions to the compiler. For example, the use of @override annotation is to instruct the compiler that the annotated method is overriding the method.
2. Compile-time instructors
Annotations provide compile-time instructions to the compiler that we can later use them using software build tools for generating XML files, code, etc.
3. Runtime instructions
We can define annotations so that they can be available at runtime and we can access them using Java reflection.
Where we can use Annotations in Java?
We can apply Annotations to classes, interfaces, methods, and fields. For example, we apply the override annotation to the below method:
@Override void myMethod() { //Do something }
This annotation is instructing the compiler that myMethod() is an overriding method that is overriding the method (myMethod()) of the superclass.
Conclusion
Hence, in this Java tutorial, we learned about annotation in java and types of annotation in Java. We discussed Marker, Single Value, Type, and Full Java Annotations.
In addition, we also discussed Predefined/ Standard or built-in annotations in Java. At last, we also learned the reasons to use Annotations and where to apply them.