Java Annotation is a tag that represents the metadata i.e. attached with class, interface, methods or fields to indicate some additional information which can be used by java compiler and JVM.
Some points about Annotations are:
- Annotations start with ‘@’ and can contain attribute/value pairs called elements
- 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
Couple of rules about Annotations are:
- Annotations function a lot like interfaces.
- Annotations establish relationships that make it easier to manage data about our application
- Annotations ascribes custom information on the declaration where it is defined.
- Annotations are optional metadata and by themselves do not do anything.
Hierarchy of Annotations in Java
Custom Annotations
Java allows you to create your own metadata in form of custom annotations. You can create your own annotations for specific purposes and use them as well.
To create a custom annotation, you must use the keyword “@interface“. Other important things to remember while creating custom annotations are listed below:
- Each method declaration defines an element of the annotation type.
- Method declarations must not have any parameters or a throws clause.
- Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types.
- Methods can have default values.
Example 1: Without Any Elements
1 2 3 4 5 6 7 8 9 |
// Declares the annotation DemoAnnotation without any value public @interface DemoAnnotation { } //Use the annotation like below @DemoAnnotation public void toggle() { } |
Example 2: Required Elements
1 2 3 4 5 6 7 8 9 |
public @interface Author { String first(); String last(); } //Use the annotation like below @Author(first = "Lokesh", last = "Gupta") Book book = new Book(); |
Example 3 : Mixing Required and Optional Elements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public @interface TravelRequest { int id(); String synopsis(); String engineer() default "[unassigned]"; String date() default "[unimplemented]"; } //Use the annotation like below @TravelRequest( id = 112233, synopsis = "Teleport me", engineer = "Mr. John Carter", date = "04/01/3007" ) public static void sendMeToMars () { } |
Example 4 : Creating a value() Element
1 2 3 4 5 6 7 8 9 10 |
//Creating value() Element public @interface Injured{ String t1() default "t1"; String value() default "root"; int age() default 1; } @Injured("Broken Demo") public class Monkey{ } @Injured(value="Test") public class Lion{ } @Injured public class Tiger{ } |
Example 5: Passing an Array of Values
1 2 3 4 5 6 7 8 |
public @interface Music{ String musicTypes(); } public class Student{ @Music(musicTypes={"Rock and Roll"}) String fav; @Music(musicTypes="Classical") String disLiked; } |
Build-In Annotations
@Target
Use @Target annotation to restrict the usage of new annotation on certain java elements such as class, interface or methods. After specifying the targets, you will be able to use the new annotation on given elements only.
1 2 3 4 5 6 7 8 9 |
import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.PACKAGE, ElementType.PARAMETER}) public @interface MyCustomAnnotation { //Some other code } |
@Retention
This annotation specifies how the marked annotation is stored in java runtime. Whether it is limited to source code only, embedded into the generated class file, or it will be available at runtime through reflection as well.
1 2 3 4 5 6 7 8 9 10 |
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; //@Retention(RetentionPolicy.CLASS) @Retention(RetentionPolicy.RUNTIME) //@Retention(RetentionPolicy.SOURCE) public @interface MyCustomAnnotation { //some code } |
@Documented
This annotation indicates that new annotation should be included into java documents generated by java document generator tools.
1 2 3 4 5 6 |
import java.lang.annotation.Documented; @Documented public @interface MyCustomAnnotation { //Some other code } |
@Inherited
When this annotation is applied to a class, subclasses will inherit the annotation information found in parent class.
For Example: @MyCustomAnnotation annotation is applied to both TestAnnotation and TestCheckAnnotation class due to @Inherited annotation in custom annotation.
1 2 3 4 5 6 7 8 9 10 11 |
import java.lang.annotation.Inherited; @Inherited public @interface MyCustomAnnotation { //Some other code } //TestAnnotation.java @MyCustomAnnotation public class TestAnnotation{} //TestCheckAnnotation.java public class TestCheckAnnotation extend TestAnnotation{} |
@Repeatable
By default, an annotation is applied on a java element only once. But, by any requirement, you have to apply a annotation more than once, then use @Repeatable
annotation on your new annotation.
1 2 3 4 5 6 |
@Repeatable(Schedules.class) public @interface Schedule { ... } @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... } |
Common Annotations
@Override
This annotation checks that the annotated method is overridden method. It causes a compile time “error” if the annotated method is not found in one of the parent classes or implemented interfaces. Very useful annotation and I will recommend to use it frequently.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class DemoClass { //some code @Override public String toString() { return super.toString(); } @Override public int hashCode() { return super.hashCode(); } } |
@Deprecated
Use this annotation on methods or classes which you need to mark as deprecated. Any class that will try to use this deprecated class or method, will get a compiler “warning“.
1 2 3 4 5 |
@Deprecated public Integer myMethod() { return null; } |
@SuppressWarnings
This annotation instructs the compiler to suppress the compile time warnings specified in the annotation parameters. e.g. to ignore the warnings of unused class attributes and methods use @SuppressWarnings("unused")
either for a given attribute or at class level for all the unused attributes and unused methods.
1 2 3 4 5 6 7 8 9 10 11 |
@SuppressWarnings("unused") public class DemoClass { //@SuppressWarnings("unused") private String str = null; //@SuppressWarnings("unused") private String getString(){ return this.str; } } |
@SafeVarargs
Marker annotations indicates that method does not perform any potential unsafe operations on its varargs parameters. It can be applied only constructors or methods that can not be overridden(private, static or final)
1 2 3 4 |
public static <T> List<T> list( final T... items ) { return Arrays.asList( items ); } |
@FunctionalInterface
This annotation is used to mark an interface as functional interface which are introduced in java 8. To read more about functional interfaces please follow the linked post.
1 2 3 4 |
@FunctionalInterface public interface MyFirstFunctionalInterface { public void doSomeWork(); } |
Leave a Reply