Introduction
- Introduced in JDK 1.5
- One of the biggest ever feature added in Java.
- A form of syntactic metadata that can be added to Java source code. Its basically Data about Data.
- Annotations don't do anything on their own, they don't do any processing. They act like a modifier and become useful only when they are processed.
- Annotations can be processed at compile time, run time or deployment time.
- Annotations are tags that we insert into our code, to be processed by tools like compiler, deployment tools or other external packages. Annotations are part of the code.
- Can be embedded in class files generated by the compiler and may be retained by the Java VM to be made retrievable at run-time.(Reference: Retention policy)
- Prior to Annotations, Java provided only ad-hoc and non-standardized mechanism, including Serializable interface (other market interfaces), transient modifier, Javadoc comments, @deprecated tag in comments.One of the main reasons for adding annotation and metadata to the Java platform is to enable development and runtime tools to have a common infrastructure.
- Annotations are part of java code, Java Docs are not.
- java.lang.annotations package provides library support for the Java programming language annotation facility.
- Normally a developer needn't create Annotations.
- Annotation-based programming is an extensible mechanism for generating application artifacts, packaging the application, and readying the application for execution.
- Annotation-based
programming offers a set of tags and a processing mechanism that allow
you to embed additional metadata into code. Application then uses this
additional metadata to derive the artifacts required to execute the
application in a J2EE environment.
Defining Annotations:
public @interface TestAnno
{
String str(); // It can never has any parameters.
int count();
}
{
@TestAnno (str="MyFirstAnnoTest", count=1001)
// When a element is given a value only name is used,
// paranthesis are not used.
public static void main(String[] args)
{
...
}
}
{
String str(); // It can never has any parameters.
int count();
}
Implementation Key points:
- @interface keyword is used to define annotations.
- Annotation types are a form of interface.
- Annotation elements must be compile time constant values.
- There is no restriction of the type of annotation element.
- All annotations consist solely of method declarations. These method declarations are called elements.
- The declarations must not have any formal parameters or a throw clause.
- java.lang.annotation.Annotation is super-interface for all annotations.
- Annotations cannot include the extends clause.
- Annotations can be applied to any declaration, ex. classes, methods, fields, parameters, enum, constants or even an annotation type.
- There is a default value element in the annotations.
- Annotations cannot use Generics, no generic member type, no type parameters.
{
@TestAnno (str="MyFirstAnnoTest", count=1001)
// When a element is given a value only name is used,
// paranthesis are not used.
public static void main(String[] args)
{
...
}
}
- If the annotation has no elements, then the parentheses can be omitted. Ex @Override.
- If there is just one element named value, then the name can be omitted. Ex
- @SuppressWarnings(value = "unchecked")
- @SuppressWarnings("unchecked")
- It is also possible to use multiple annotations on the same declaration:
- @TestAnno (str="MyFirstAnnoTest", count=1001)
@SuppressWarnings("unchecked")
class TestClass { ... }
Annotation Uses:
- Annotations helps moving away redundant code, remove config xml (ex. deployment descriptor), adds extra checks (ex. @override).
- Provide information to Compiler -
- To detect errors or suppress warnings (@Deprecated, @Override, @SuppressWarning)
- Compile-time and deployment-time processing -
- Software tools can process annotation information to generate code, XML files, and so forth. Ex @WebServlet, @WebInitParam, @WebFilter, @WebListener etc.
- Runtime processing -
- Marker Annotations
Default Value for Annotation elements
- We can provide default values to annotations, that will be assigned if no value is specified.
- A default value is specified by adding a default clause to a member's declaration.
- Syntax:
- type member() default default-value
- default-value must be type compatible with member type.
public @interface TestAnno
{
String str() default "testString" ;
int count() default -1 ;
}
{
String value() ;
}
{
String str() default "testString" ;
int count() default -1 ;
}
Marker Annotations
- Similar in concept with Marker interface - no member methods with sole purpose of marking a declaration.
Single-Member Annotations
- As the name suggests, only one annotation contains only one member.
- member name should be value.
- Uniqueness - allows to use shorthand, no need to specify the name of the member.
{
String value() ;
}
@TestSingleAnno("Testing Single Annotation")
public static void main(Sting[] args)
{
...
}
Java SE Predefined Annotations:
- @Deprecated
- Defined in java.lang package.
- Introduced in Java 1.5
- When @Deprecated is used, documentation (javadoc @deprecated comment) should reflect why open is deprecated and what to use instead.
- @Override
- Defined in java.lang package.
- Introduced in Java 1.5
- If a method marked with @Override fails to correctly override a method, the compiler throws an error.
- It helps to prevent errors.
- @SuppressWarning
- Defined in java.lang package.
- Introduced in Java 1.5 Instructs the compiler to suppress specific warnings that it would otherwise generate.
- Warnings like unused variables, deprecated methods will be suppressed by compiler.
- Ex. @SuppressWarnings("deprecation")
- Ex. @SuppressWarnings({"unchecked", "deprecation"})
- @SafeVarargs
- Defined in java.lang package.
- Introduced in Java 1.7
- It asserts that the code does not perform potentially unsafe operations on its varargs parameter.
- Unchecked warnings relating to varargs usage are suppressed.
- @FunctionalInterface
- Defined in java.lang package.
- Introduced in Java 1.8
- An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification.
- Conceptually, a functional interface has exactly one abstract method.
- However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.
- If a type is annotated with this annotation type, compilers are required to generate an error message unless:
- The type is an interface type and not an annotation type, enum, or class.
- The annotated type satisfies the requirements of a functional interface.
Meta-Annotations
It is information about annotation.There are several meta-annotation types defined in java.lang.annotati
- @Retention
- Specifies how the marked annotation is stored, at what point, its discarded.
- Java defines 3 such policies encapsulated in java.lang.annotation.RetentionPolicy enumeration - SOURCE, CLASS, RUNTIME.
- SOURCE - Retained only in source file and discarded during compilation.
- CLASS - Stored in .class file during compilation, but its not available through JVM during runtime.
- RUNTIME - Stored in .class file during compilation, and available through JVM during runtime. It offers the greatest annotation persistence.
- Default Retention level is CLASS. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS
- Ex. @Retention(RetentionPolicy.RUNTIME)
- @Documented
- Indicates whenever the specified annotation is used those elements should be documented using the Javadoc tool.
- By default, annotations are not included in Javadoc.
- To make the information in @TestAnno appear in Javadoc-generated documentation, you must annotate the @TestAnno definition with the @Documented annotation:
import java.lang.annotation.*;
@Documented
public @interface TestAnno
{
String str(); // It can never has any parameters.
int count();
}
- @Target
- Indicates the kinds of program element to which an annotation type is applicable.
- If a Target meta-annotation is not present on an annotation type declaration, the declared type may be used on any program element.
- A target annotation specifies one of the following element types as its value:
- ElementType.ANNOTATION_TYPE can be applied to an annotation type.
- ElementType.CONSTRUCTOR can be applied to a constructor.
- ElementType.FIELD can be applied to a field or property.
- ElementType.LOCAL_VARIABLE can be applied to a local variable.
- ElementType.METHOD can be applied to a method-level annotation.
- ElementType.PACKAGE can be applied to a package declaration.
- ElementType.PARAMETER can be applied to the parameters of a method.
- ElementType.TYPE can be applied to any element of a class.
ElementType.FIELD})
public @interface TestAnno {
...
}
@Target(ElementType.ANNOTATION_TYPE)
public @interface TestAnno {
...
}
public @interface TestAnno {
...
}
@Target(ElementType.ANNOTATION_TYPE)
public @interface TestAnno {
...
}
- @Inherited
- Indicates that the annotation type is automatically inherited from the super class.
- This annotation applies only to class declarations.
- By Default a class doesn't inherit annotations of its super class.
- When the user queries the annotation type and the class has no annotation for this type, the class' superclass is queried for the annotation type.
Java 8 Enhancements
Type Annotations and Pluggable Type Systems
- Before the Java SE 8 release, annotations could only be applied to declarations.
- As of the Java SE 8 release, annotations can also be applied to any type use.
- A few examples of where types are used are class instance creation expressions (new), casts, implements clauses, and throws clauses.
- This form of annotation is called a type annotation, following are few examples:
myString = (@NonNull String) str; //Type cast
@NonNull String str;
class UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... } //implements clause
void monitorTemperature() throws
@Critical TemperatureException { ... } //Thrown exception declaration
- Type annotations were created to support improved analysis of Java programs way of ensuring stronger type checking.
- The Java SE 8 release does not provide a type checking framework.
- It allows you to write (or download) a type checking framework that is implemented as one or more pluggable modules that are used in conjunction with the Java compiler.
@Repeatable
- Indicates that the marked annotation can be applied more than once to the same declaration or type use.
- There are situations where you want to apply same annotation multiple times to a declaration or type use. Following are few examples:
- A Project could fall under several project categories.
- A process needs to be scheduled for multiple time.
- An event could be observed by multiple roles.
public @interface Schedule { ... }
//container annotation for repeatable
public @interface Schedules {
Schedule[] value;
}
//custom annotation with repeatable
//The value of @Repeatable meta-annotation is container annotation.
@Repeatable(Schedules.class)
public @interface Schedule { ... }
No comments:
Post a Comment