In Java, an annotation is a form of syntactic metadata that can be added to Java source code. It provides data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate. Classes, methods, variables, parameters and packages are allowed to be annotated.
The Java Language Specification describes Annotations as follows:
Annotations may appear before types or declarations. It is possible for them to appear in a place where they could apply to both a type or a declaration.
What exactly an annotation applies to is governed by the "meta-annotation" @Target. See "Defining annotation types" for more information.
Annotations are used for a multitude of purposes. Frameworks like Spring and Spring-MVC make use of annotations to define where Dependencies should be injected or where requests should be routed.
Other frameworks use annotations for code-generation. Lombok and JPA are prime examples, that use annotations to generate Java (and SQL) code.
This topic aims to provide a comprehensive overview of:
Annotation types are defined with @interface. Parameters are defined similar to methods of a regular interface.
@interface MyAnnotation { String param1(); boolean param2(); int[] param3(); // array parameter }
Default values
@interface MyAnnotation { String param1() default "someValue"; boolean param2() default true; int[] param3() default {}; }
Meta-Annotations
Meta-annotations are annotations that can be applied to annotation types. Special predefined meta-annotation define how annotation types can be used.
@Target
The @Target meta-annotation restricts the types the annotation can be applied to.
@Target(ElementType.METHOD) @interface MyAnnotation { // this annotation can only be applied to methods }
Multiple values can be added using array notation, e.g. @Target({ElementType.FIELD, ElementType.TYPE})
Available Values
ElementType | Target | Example Usage on Target Element |
---|---|---|
ANNOTATION_TYPE | annotation types | @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation {} |
CONSTRUCTOR | constructors | @MyAnnotation public MyClass() {} |
FIELD | fields, enum constants | @XmlAttribute private int count; |
LOCAL_VARIABLE | variable declarations inside methods | for (@LoopVariable int i = 0; i < 100; i++) { @Unused String resultVariable; } |
PACKAGE | package (in package-info.java) | @Deprecated package very.old; |
METHOD | methods | @XmlElement public int getCount() {...} |
PARAMETER | method/constructor parameters | public Rectangle(@NamedArg("width") double width, @NamedArg("height") double height) {...} |
TYPE | classes, interfaces, enums | @XmlRootElement public class Report {} |
Version ≥ Java SE 8
ElementType | target | example usage on target element |
---|---|---|
TYPE_PARAMETER | Type parameter declarations | public <@MyAnnotation T> void f(T t) {} |
TYPE_USE | Use of a type | Object o = "42";ing s = (@MyAnnotation String) o; |
@Retention
The @Retention meta-annotation defines the annotation visibility during the applications compilation process or execution. By default, annotations are included in .class files, but are not visible at runtime. To make an annotation accessible at runtime, RetentionPolicy.RUNTIME has to be set on that annotation.
@Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { // this annotation can be accessed with reflections at runtime }
Available Values
RetentionPolicy | Effect |
---|---|
CLASS | The annotation is available in the .class file, but not at runtime |
RUNTIME | The annotation is available at runtime and can be accessed via reflection |
SOURCE | The annotation is available at compile time, but not added to the .class files. The annotation can be used e.g. by an annotation processor. |
@Documented
The @Documented meta-annotation is used to mark annotations whose usage should be documented by API documentation generators like javadoc. It has no values. With @Documented, all classes that use the annotation will list it on their generated documentation page. Without @Documented, it's not possible to see which classes use the annotation in the documentation.
@Inherited
The @Inherited meta-annotation is relevant to annotations that are applied to classes. It has no values. Marking an annotation as @Inherited alters the way that annotation querying works.
Note that only the super-classes are queried: any annotations attached to interfaces in the classes hierarchy will be ignored.
@Repeatable
The @Repeatable meta-annotation was added in Java 8. It indicates that multiple instances of the annotation can be attached to the annotation's target. This meta-annotation has no values.
Java's Reflection API allows the programmer to perform various checks and operations on class fields, methods and annotations during runtime. However, in order for an annotation to be at all visible at runtime, the RetentionPolicy must be changed to RUNTIME, as demonstrated in the example below:
@interface MyDefaultAnnotation { } @Retention(RetentionPolicy.RUNTIME) @interface MyRuntimeVisibleAnnotation { } public class AnnotationAtRuntimeTest { @MyDefaultAnnotation static class RuntimeCheck1 { } @MyRuntimeVisibleAnnotation static class RuntimeCheck2 { } public static void main(String[] args) { Annotation[] annotationsByType = RuntimeCheck1.class.getAnnotations(); Annotation[] annotationsByType2 = RuntimeCheck2.class.getAnnotations(); System.out.println("default retention: " + Arrays.toString(annotationsByType)); System.out.println("runtime retention: " + Arrays.toString(annotationsByType2)); } }
Learn All in Tamil © Designed & Developed By Tutor Joes | Privacy Policy | Terms & Conditions