Annotations in Java provide additional information to the compiler and JVM. An annotation is a tag representing metadata about classes, interfaces, variables, methods, or fields. Annotations do not impact the execution of the code that they annotate. Some of the characteristics of annotations are:
- Begin with ‘@’
- Do not alter the execution of the program
- Provide supplemental information and help to link metadata with elements of a program such as classes, variables, constructs, methods, etc.
- Are different from comments since they can affect how the program is treated by the compiler
Hierarchy of Annotations in Java
Example
class Flower {
public void displayInfo() {
System.out.println("I am a flower.");
}
}
class Rose extends Flower {
@Override
public void displayInfo() {
System.out.println("I am a rose.");
}
}
class Main {
public static void main(String[] args) {
Rose r1 = new Rose();
r1.displayInfo();
}
}
Output
I am a rose
In the above example, both the superclass and subclass include the method displayInfo(). However, when the method is called, instead of the method of the superclass, the method of the subclass is called.
Categories of Annotations
Annotations can be categorized broadly into 5 categories:
Category 1: Marker Annotations
The marker annotation is used to mark a declaration. It does not include any members or data. Only the presence of a marker annotation as an annotation is sufficient. An example of Marker Annotation is @Override
Example
@TestAnnotation()
Category 2: Single value Annotations
A single value annotation consists of a single member only. This annotation allows a shorthand form to specify the value of the member. There is no need to specify the name of the member, only the value of the member has to be specified. There must, however, be a value for the name of the member in order to use this category of annotation.
Example
@interface AnnotationName{
Int value();
}
@interface AnnotationName{
int value() default 0;
}
To apply single value annotation, use
@AnnotationName(value=6)
Any value can be assigned.
Category 3: Full Annotations
Full Annotations include multiple data members, values, names, and pairs.
Example
@TestAnnotation(owner= ”Ravi”, value= ”Class ”)
Category 4: Type Annotations
As the name suggests, Type Annotations are applied at any place where a type is being used. For instance, the return type of a method can be annotated. Type Annotations are declared with @Target Annotation
Example
// Java Program to Demonstrate Type Annotation
// Importing required classes
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// Using target annotation to annotate a type
@Target(ElementType.TYPE_USE)
// Declaring a simple type annotation
@interface TypeAnnoExample{}
// Main class
public class GFG {
// Main driver method
public static void main(String[] args) {
// Annotating the type of a string
@TypeAnnoExample String string = "This is an example of type annotation";
System.out.println(string);
abc();
}
// Annotating return type of a function
static @TypeAnnoExample int abc() {
System.out.println("The return type of this function is annotated");
return 0;
}
}
Output
This is an example of type annotation
The return type of this function is annotated
Category 5: Repeating Annotations
It is possible to apply an annotation to a single item more than once using Repeating Annotations. @Repeatable annotation which is available in java.lang.annotation package is used to annotate the repeating annotations. The container type for the repeatable annotation is specified by the value field of this annotation. The container is specified as an annotation and its value field consists of an array of the repeatable annotation type. In order to use this type of annotation, the container annotation is created first and the annotation type is then specified as an argument to the @Repeatable annotation.
Example
// Java Program to Demonstrate a Repeatable Annotation
// Importing required classes
import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
// Make Words annotation repeatable
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyRepeatedAnnoDemo.class)
@interface Words
{
String word() default "Welcome";
int value() default 0;
}
// Create container annotation
@Retention(RetentionPolicy.RUNTIME)
@interface MyRepeatedAnnoDemo
{
Words[] value();
}
public class Main {
// Repeat Words on newMethod
@Words(word = "This", value = 1)
@Words(word = "That", value = 2)
public static void newMethod()
{
Main obj = new Main();
try {
Class<?> c = obj.getClass();
// Obtain the annotation for newMethod
Method m = c.getMethod("newMethod");
// Display the repeated annotation
Annotation anno
= m.getAnnotation(MyRepeatedAnnoDemo.class);
System.out.println(anno);
}
catch (NoSuchMethodException e) {
System.out.println(e);
}
}
public static void main(String[] args) { newMethod(); }
}
Output
@MyRepeatedAnnos(value={@Words(value=1, word="This"), @Words(value=2, word="That")})
Types of Annotations
Predefined/ Standard Annotations
As indicated in the hierarchy of annotations above, Java provides built-in or standard annotations. @Deprecated, @Override, and @SuppressWarnings are available in java.lang & @Retention, @Documented, @Target, and @Inherited are imported from java.lang.annotation package.
Annotation 1: @Deprecated
The @Deprecated annotation is used to indicate that the class, field, or method marked is no longer in use and has been replaced by a newer form. Whenever a class, field, or method marked with the @Deprecated annotation is used, the compiler gives a warning message that a deprecated class, field, or method is used. When an element has been deprecated, the Javadoc tag @deprecated tag must be used. There is a difference between the @deprecated tag and @Deprecated annotation. While the @deprecated tag is used for documentation, the @Deprecated annotation is used for runtime reflection.
Example
public class DeprecatedDemo
{
@Deprecated
public void Display()
{
System.out.println("Deprecateddemo display()");
}
public static void main(String args[])
{
DeprecatedDemo d1 = new DeprecatedDemo();
d1.Display();
}
}
Output
Deprecateddemo display()
Annotation 2: @Override
@Override is a marker annotation that can only be used on methods. A method that is annotated with @Override must override a method from the superclass. A compile-time error occurs if the method does not override the method from the superclass. This ensures that the superclass method is overridden and not overloaded. The code becomes more readable and maintenance issues can be avoided.
Example
// Java Program to Illustrate Override Annotation
// Class 1
class ParentClass
{
public void Display()
{
System.out.println("Parent Class Display() Method");
}
public static void main(String args[])
{
ParentClass t1 = new ChildClass();
t1.Display();
}
}
// Class 2
// Extending above class
class ChildClass extends ParentClass
{
@Override
public void Display()
{
System.out.println("Child Class Display() Method");
}
}
Output
Child Class Display() Method
Annotation 3: @SuppressWarnings
@SuppressWarnings is used to inform the compiler to suppress the specified compiler warnings. This is done by specifying the warnings to be suppressed by specific names. It can be applied to any type of declaration. There are two categories under which Java groups warnings - deprecated and unchecked. When a legacy code interfaces with a code that uses generics, an unchecked warning is generated.
Example
// Java Program to illustrate SuppressWarnings Annotation
// Class 1
class DeprecatedDemo
{
@Deprecated
public void Display()
{
System.out.println("Deprecateddemo display()");
}
}
// Class 2
public class SuppressWarningDemo
{
// If we comment below annotation, program generates
// warning
@SuppressWarnings({"checked", "deprecation"})
public static void main(String args[])
{
DeprecatedDemo d1 = new DeprecatedDemo();
d1.Display();
}
}
Output
Deprecateddemo display()
Annotation 4: @Documented
@Documented is a marker interface that specifies to a tool that a particular annotation has to be documented. Annotations are not included in the ‘Javadoc’ comments. By using @Documented annotation in the code, tools like Javadoc can process and include the annotated type in the generated document.
Annotation 5: @Target
@Target is used as an annotation to another annotation. The @Target annotation takes only one argument and this argument should be a constant value from the ElementType enumeration. The constants along with the corresponding declaration ars shown in the table below:
Target Constant |
Applied to Annotation |
ANNOTATION_TYPE |
Another Annotation |
CONSTRUCTOR |
Constructor |
FIELD |
Field |
LOCAL_VARIABLE |
Local Variable |
METHOD |
Method |
PACKAGE |
Package |
PARAMETER |
Parameter |
TYPE |
Class, Interface, or enumeration |
One or more values can be specified in a @Target annotation by using a braces-delimited list. For example, to specify an annotation that applies to fields and local variables, the following annotation can be used
@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
Annotation 6: @Inherited
@Inherited annotation is a marker annotation that is only used on annotation declaration. Only the annotations that are used on class declarations are affected by it. @Inherited causes the subclass to inherit the annotation from a superclass. Hence, when there is a request for a specific annotation to a subclass and it is not present in the subclass, the superclass is checked. If the annotation is present in the superclass and it is annotated with @Inherited, the annotation is returned.
Annotation 7: User-defined (Custom)
To annotate program elements, i.e. variables, constructors, methods, etc. user-defined annotations can be used. The user-defined annotations can be applied to the elements Ii.e. variables, constructors, classes, methods) just before their declaration.
Annotations are created by using @interface and are followed by the annotation name. An annotation can also have elements. They appear as methods but the implementation should not be provided for these elements. All the annotations extend java.lang.annotation.Annotation interface. The annotations cannot include the extended clause.
Example
// Java Program to Demonstrate User-defined Annotations
package source;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// User-defined annotation
@Documented
@Retention(RetentionPolicy.RUNTIME)
@ interface AnnotationDemo
{
String Developer() default "Ravi";
String Expirydate();
} // will be retained at runtime
// Driver class that uses @AnnotationDemo
public class Demo
{
@AnnotationDemo(Developer="Ravi", Expirydate="26-03-2020")
void fun1()
{
System.out.println("Demo method 1");
}
@AnnotationDemo(Developer="Kiran", Expirydate="26-03-2021")
void fun2()
{
System.out.println("Demo method 2");
}
public static void main(String args[])
{
System.out.println("Welcome");
}
}
Output
Welcome
Use of Annotations
Annotations are used for the following purposes:
- Instructions to the compiler: There are three types of built-in annotations @Deprecated, @Override, @SuppressWarnings that can be used to give instructions to the compiler, detect errors, and suppress warnings. For example, @Override annotation can be used to instruct the compiler to denote that the annotated method is overriding the method.
- Compile-time Instructions: Software build tools can generate code, XML files, and more by using the compile-time instructions that the annotations provide.
- Runtime Instructions: Annotations can also be defined to provide instructions to the program at runtime. These annotations can be accessed using Java Reflection.
Conclusion
Hope this article was able to give you a thorough understanding about annotations in Java. If you are looking to enhance your software development skills further, we would recommend you check Simplilearn’s Post Graduate Program in Full Stack Web Development. This course, designed in collaboration with Caltech CTME, can help you hone the required skills and make you job-ready in no time.
If you have any questions or doubts, feel free to post them in the comments below. Our team will review and get back to you with the solutions at the earliest.