A Java Annotation serves as a marker that conveys metadata, such as being linked to a class, interface, methods, or fields to signify supplementary details that can be leveraged by the Java compiler and JVM.
In Java, annotations serve as a means to offer supplementary details, presenting an alternative to XML and Java marker interfaces.
Initially, we will explore predefined annotations before progressing to the development and application of personalized annotations.
Built-In Java Annotations
Java provides a variety of pre-existing annotations. These annotations can be utilized on Java code itself or on other annotations within the codebase.
Built-In Java Annotations used in Java code
- @Override
- @SuppressWarnings
- @Deprecated
- @Target
- @Retention
- @Inherited
- @Documented
Built-In Java Annotations used in other annotations
Understanding Built-In Annotations
Let's understand the built-in annotations first.
@Override
The use of the @Override annotation guarantees that a method in a subclass is indeed overriding a method in its parent class. Failure to do so will result in a compile-time error.
Occasionally, we may make errors like spelling mistakes when coding. To ensure that a method is properly overridden, it is advisable to use the @Override annotation for added assurance.
Example
class Animal{
void eatSomething(){System.out.println("eating something");}
}
class Dog extends Animal{
@Override
void eatsomething(){System.out.println("eating foods");}//should be eatSomething
}
class TestAnnotation1{
public static void main(String args[]){
Animal a=new Dog();
a.eatSomething();
}}
Output:
Comple Time Error
@SuppressWarnings
The @SuppressWarnings annotation is utilized to silence warnings generated by the compiler.
Example
import java.util.*;
class TestAnnotation2{
@SuppressWarnings("unchecked")
public static void main(String args[]){
ArrayList list=new ArrayList();
list.add("sonoo");
list.add("vimal");
list.add("ratan");
for(Object obj:list)
System.out.println(obj);
}}
Output:
sonoo
vimal
ratan
By eliminating the @SuppressWarnings("unchecked") annotation, warnings will be displayed during compilation due to the utilization of non-generic collections.
@Deprecated
The presence of the @Deprecated annotation indicates that a method is outdated, prompting the compiler to issue a warning. This serves as a notification to users that the method may be eliminated in upcoming releases, advising against its use.
Example
class A{
void m(){System.out.println("hello m");}
@Deprecated
void n(){System.out.println("hello n");}
}
class TestAnnotation3{
public static void main(String args[]){
A a=new A();
a.n();
}}
At Compile Time:
Note: Test.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
At Runtime:
hello n
Java Custom Annotations
Creating custom annotations in Java, also known as user-defined annotations, is a straightforward process. Annotations are declared using the @interface keyword. For instance:
@interface MyAnnotation{}
Here, MyAnnotation is the custom annotation name.
Points to remember for java custom annotation signature
There are few points that should be remembered by the programmer.
- Method should not have any throws clauses
- Method should return one of the following: primitive data types, String, Class, enum or array of these data types.
- Method should not have any parameter.
- We should attach @ just before interface keyword to define annotation.
- It may assign a default value to the method.
Types of Annotation
There are three types of annotations.
- Marker Annotation
- Single-Value Annotation
- Multi-Value Annotation
1) Marker Annotation
A marker annotation is an annotation that does not contain any methods. For instance:
@interface MyAnnotation{}
The annotations @Override and @Deprecated are known as marker annotations in Java programming.
2) Single-Value Annotation
A single-value annotation, also known as an annotation with only one method, is an annotation that contains a single method. An illustration of this is:
@interface MyAnnotation{
int value();
}
It is also possible to supply a default value, as illustrated below:
@interface MyAnnotation{
int value() default 0;
}
How to apply Single-Value Annotation
Let's examine the code snippet demonstrating the implementation of a single value annotation.
@MyAnnotation(value=10)
The value can be anything.
3) Multi-Value Annotation
A multi-value annotation refers to an annotation that contains multiple methods. For instance:
@interface MyAnnotation{
int value1();
String value2();
String value3();
}
}
It is also possible to specify a default value, as shown in the following example:
@interface MyAnnotation{
int value1() default 1;
String value2() default "";
String value3() default "xyz";
}
How to apply Multi-Value Annotation
Let's examine the code snippet for implementing the multi-value annotation.
@MyAnnotation(value1=10,value2="Arun Kumar",value3="Ghaziabad")
Built-in Annotations used in custom annotations in java
- @Target
- @Retention
- @Inherited
- @Documented
@Target
The @Target tag is utilized to indicate the type at which the annotation is applied.
The enum java.lang.annotation.ElementType provides various constants that define the type of element where an annotation can be used, including declarations like TYPE, METHOD, and FIELD. Let's explore the constants available in the ElementType enum:
| Element Types | Where the annotation can be applied |
|---|---|
TYPE |
class, interface or enumeration |
| FIELD | fields |
| METHOD | methods |
| CONSTRUCTOR | constructors |
| LOCAL_VARIABLE | local variables |
| ANNOTATION_TYPE | annotation type |
| PARAMETER | parameter |
Example to specify annoation for a class
@Target(ElementType.TYPE)
@interface MyAnnotation{
int value1();
String value2();
}
Example to specify annotation for a class, methods or fields
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface MyAnnotation{
int value1();
String value2();
}
@Retention
The @Retention annotation is utilized to define the scope of availability for an annotation.
| RetentionPolicy | Availability |
|---|---|
| RetentionPolicy.SOURCE | refers to the source code, discarded during compilation. It will not be available in the compiled class. |
| RetentionPolicy.CLASS | refers to the .class file, available to java compiler but not to JVM . It is included in the class file. |
| RetentionPolicy.RUNTIME | refers to the runtime, available to java compiler and JVM . |
Example to specify the RetentionPolicy
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation{
int value1();
String value2();
}
Example of custom annotation: creating, applying and accessing annotation
Let's explore a basic illustration demonstrating the process of creating, utilizing, and retrieving annotations.
Example
//Creating annotation
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation{
int value();
}
//Applying annotation
class Hello{
@MyAnnotation(value=10)
public void sayHello(){System.out.println("hello annotation");}
}
//Accessing annotation
class TestCustomAnnotation1{
public static void main(String args[])throws Exception{
Hello h=new Hello();
Method m=h.getClass().getMethod("sayHello");
MyAnnotation manno=m.getAnnotation(MyAnnotation.class);
System.out.println("value is: "+manno.value());
}}
Output:
value is: 10
How built-in annotaions are used in real scenario?
In a practical setting, a Java developer is only required to utilize annotations. The creation and retrieval of annotations are handled by the implementation provider. Additional operations related to the annotation are carried out by the Java compiler or the JVM.
@Inherited
Annotations are typically not passed down to subclasses by default. However, the @Inherited annotation can be utilized to specify that an annotation should be inherited by subclasses.
@Inherited
@interface ForEveryone { }//Now it will be available to subclass also
@interface ForEveryone { }
class Superclass{}
class Subclass extends Superclass{}
@Documented
The @Documented annotation signifies that the annotated element should be documented.