- Declaring an Annotation Type
- Annotations Basics
- Where Annotations Can Be Used
- Annotations in Java
- Hierarchy of Annotations in Java
- Java
- Categories of Annotations
- Category 1: Marker Annotations
- Category 2: Single value Annotations
- Category 3: Full Annotations
- Category 4: Type Annotations
- Java
- Category 5: Repeating Annotations
- Java
- Predefined/ Standard Annotations
- Annotation 1: @Deprecated
- Java
- Annotation 2: @Override
- Java
- Annotation 3: @SuppressWarnings
- Java
- Annotation 4: @Documented
- Annotation 5: @Target
- Annotation 6: @Inherited
- Annotation 7: User-defined (Custom)
Declaring an Annotation Type
Suppose that a software group traditionally starts the body of every class with comments providing important information:
public class Generation3List extends Generation2List < // Author: John Doe // Date: 3/17/2002 // Current revision: 6 // Last modified: 4/12/2004 // By: Jane Doe // Reviewers: Alice, Bill, Cindy // class code goes here >
To add this same metadata with an annotation, you must first define the annotation type. The syntax for doing this is:
The annotation type definition looks similar to an interface definition where the keyword interface is preceded by the at sign ( @ ) (@ = AT, as in annotation type). Annotation types are a form of interface, which will be covered in a later lesson. For the moment, you do not need to understand interfaces.
The body of the previous annotation definition contains annotation type element declarations, which look a lot like methods. Note that they can define optional default values.
After the annotation type is defined, you can use annotations of that type, with the values filled in, like this:
@ClassPreamble ( author = "John Doe", date = "3/17/2002", currentRevision = 6, lastModified = "4/12/2004", lastModifiedBy = "Jane Doe", // Note array notation reviewers = ) public class Generation3List extends Generation2List < // class code goes here >
Note: To make the information in @ClassPreamble appear in Javadoc-generated documentation, you must annotate the @ClassPreamble definition with the @Documented annotation:
// import this to use @Documented
import java.lang.annotation.*; @Documented @interface ClassPreamble < // Annotation element definitions >
Annotations Basics
In its simplest form, an annotation looks like the following:
The at sign character ( @ ) indicates to the compiler that what follows is an annotation. In the following example, the annotation’s name is Override :
@Override void mySuperMethod()
The annotation can include elements, which can be named or unnamed, and there are values for those elements:
@Author( name = «Benjamin Franklin», date = «3/27/2003» ) class MyClass
@SuppressWarnings(value = «unchecked») void myMethod()
If there is just one element named value , then the name can be omitted, as in:
@SuppressWarnings(«unchecked») void myMethod()
If the annotation has no elements, then the parentheses can be omitted, as shown in the previous @Override example.
It is also possible to use multiple annotations on the same declaration:
@Author(name = «Jane Doe») @EBook class MyClass
If the annotations have the same type, then this is called a repeating annotation:
@Author(name = «Jane Doe») @Author(name = «John Smith») class MyClass
Repeating annotations are supported as of the Java SE 8 release. For more information, see Repeating Annotations.
The annotation type can be one of the types that are defined in the java.lang or java.lang.annotation packages of the Java SE API. In the previous examples, Override and SuppressWarnings are predefined Java annotations. It is also possible to define your own annotation type. The Author and Ebook annotations in the previous example are custom annotation types.
Where Annotations Can Be Used
Annotations can be applied to declarations: declarations of classes, fields, methods, and other program elements. When used on a declaration, each annotation often appears, by convention, on its own line.
As of the Java SE 8 release, annotations can also be applied to the use of types. Here are some examples:
- Class instance creation expression:
myString = (@NonNull String) str;
class UnmodifiableList implements @Readonly List
void monitorTemperature() throws @Critical TemperatureException
This form of annotation is called a type annotation. For more information, see Type Annotations and Pluggable Type Systems.
Annotations in Java
Annotations are used to provide supplemental information about a program.
- Annotations start with ‘@’.
- Annotations do not change the action of a compiled program.
- Annotations help to associate metadata (information) to the program elements i.e. instance variables, constructors, methods, classes, etc.
- Annotations are not pure comments as they can change the way a program is treated by the compiler. See below code for example.
- Annotations basically are used to provide additional information, so could be an alternative to XML and Java marker interfaces.
Hierarchy of Annotations in Java
Implementation:
Note: This program throws compiler error because we have mentioned override, but not overridden, we have overloaded display.
Java
10: error: method does not override or implement a method from a supertype
If we remove parameter (int x) or we remove @override, the program compiles fine.
Categories of Annotations
There are broadly 5 categories of annotations as listed:
- Marker Annotations
- Single value Annotations
- Full Annotations
- Type Annotations
- Repeating Annotations
Let us discuss and we will be appending code wherever required if so.
Category 1: Marker Annotations
The only purpose is to mark a declaration. These annotations contain no members and do not consist of any data. Thus, its presence as an annotation is sufficient. Since the marker interface contains no members, simply determining whether it is present or absent is sufficient. @Override is an example of Marker Annotation.
Category 2: Single value Annotations
These annotations contain only one member and allow a shorthand form of specifying the value of the member. We only need to specify the value for that member when the annotation is applied and don’t need to specify the name of the member. However, in order to use this shorthand, the name of the member must be a value.
Category 3: Full Annotations
These annotations consist of multiple data members, names, values, pairs.
@TestAnnotation(owner=”Rahul”, value=”Class Geeks”)
Category 4: Type Annotations
These annotations can be applied to any place where a type is being used. For example, we can annotate the return type of a method. These are declared annotated with @Target annotation.
Java
I am annotated with a type annotation This function's return type is annotated
Category 5: Repeating Annotations
These are the annotations that can be applied to a single item more than once. For an annotation to be repeatable it must be annotated with the @Repeatable annotation, which is defined in the java.lang.annotation package. Its value field specifies the container type for the repeatable annotation. The container is specified as an annotation whose value field is an array of the repeatable annotation type. Hence, to create a repeatable annotation, firstly the container annotation is created, and then the annotation type is specified as an argument to the @Repeatable annotation.
Java
Predefined/ Standard Annotations
Java popularly defines seven built-in annotations as we have seen up in the hierarchy diagram.
- Four are imported from java.lang.annotation: @Retention, @Documented, @Target, and @Inherited.
- Three are included in java.lang: @Deprecated, @Override and @SuppressWarnings
Annotation 1: @Deprecated
- It is a marker annotation. It indicates that a declaration is obsolete and has been replaced by a newer form.
- The Javadoc @deprecated tag should be used when an element has been deprecated.
- @deprecated tag is for documentation and @Deprecated annotation is for runtime reflection.
- @deprecated tag has higher priority than @Deprecated annotation when both are together used.
Java
Annotation 2: @Override
It is a marker annotation that can be used only on methods. A method annotated with @Override must override a method from a superclass. If it doesn’t, a compile-time error will result (see this for example). It is used to ensure that a superclass method is actually overridden, and not simply overloaded.
Java
Annotation 3: @SuppressWarnings
It is used to inform the compiler to suppress specified compiler warnings. The warnings to suppress are specified by name, in string form. This type of annotation can be applied to any type of declaration.
Java groups warnings under two categories. They are deprecated and unchecked. Any unchecked warning is generated when a legacy code interfaces with a code that uses generics.
Java
Annotation 4: @Documented
It is a marker interface that tells a tool that an annotation is to be documented. Annotations are not included in ‘Javadoc’ comments. The use of @Documented annotation in the code enables tools like Javadoc to process it and include the annotation type information in the generated document.
Annotation 5: @Target
It is designed to be used only as an annotation to another annotation. @Target takes one argument, which must be constant from the ElementType enumeration. This argument specifies the type of declarations to which the annotation can be applied. The constants are shown below along with the type of the declaration to which they correspond.
Target Constant | Annotations Can Be 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 |
We can specify one or more of these values in a @Targetannotation. To specify multiple values, we must specify them within a braces-delimited list. For example, to specify that an annotation applies only to fields and local variables, you can use this @Target annotation: @Target() @Retention Annotation It determines where and how long the annotation is retent. The 3 values that the @Retention annotation can have:
- SOURCE: Annotations will be retained at the source level and ignored by the compiler.
- CLASS: Annotations will be retained at compile-time and ignored by the JVM.
- RUNTIME: These will be retained at runtime.
Annotation 6: @Inherited
@Inherited is a marker annotation that can be used only on annotation declaration. It affects only annotations that will be used on class declarations. @Inherited causes the annotation for a superclass to be inherited by a subclass. Therefore, when a request for a specific annotation is made to the subclass, if that annotation is not present in the subclass, then its superclass is checked. If that annotation is present in the superclass, and if it is annotated with @Inherited, then that annotation will be returned.
Annotation 7: User-defined (Custom)
User-defined annotations can be used to annotate program elements, i.e. variables, constructors, methods, etc. These annotations can be applied just before the declaration of an element (constructor, method, classes, etc).
Syntax: Declaration
[Access Specifier] @interface < DataType () [default value]; >
Do keep these certain points as rules for custom annotations before implementing user-defined annotations.
- AnnotationName is an interface.
- The parameter should not be associated with method declarations and throws clause should not be used with method declaration.
- Parameters will not have a null value but can have a default value.
- default valueis optional.
- The return type of method should be either primitive, enum, string, class name, or array of primitive, enum, string, or class name type.