Annotations is a form of metadata which provide 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.
Annotations have a number of uses, among them:
- Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
- Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
- Runtime processing — Some annotations are available to be examined at runtime.
Predefined Annotations
A set of annotation types are already predefined in the Java SE API in java.lang
. They are:
@Override
@Deprecated
@SuppressWarnings
@Override
@Override
informs the compiler that the marked method is meant to override a method in a superclass. If a method with @Override
fails to override a method in one of its superclasses, a wrong method name for example, the compiler generates an error. It can only be used for methods.
When compile class Apple, it will generate an override error because of wrong method name.
@Deprecated
It indicates that the marked element is deprecated and should no longer be used. The compiler generates a warning whenever a program uses a method, class, or field with the @Deprecated annotation.
It also has a certain “inheritance”: If we use in the code an overrided/inherited types or methods from deprecated ones, the compiler still generates a warning.
So we would get a warning when use eat() in class Orange.
@SuppressWarnings
It tells compiler to suppress specific warnings that it would otherwise generate. In the following example, a deprecated method is used but now @SuppressWarnings
causes the warning to be suppressed.
This annotation has a String[] parameter.
- @SuppressWarnings(value={ “rawtypes”, “unchecked” }) - When two warnings to suppress
- @SuppressWarnings({“unchecked”, “deprecation”}) - “value=” could be ignored
- @SuppressWarnings(“deprecation”) - We could write like this if only one parameter
The following is some common warnings:
It depends on jdk and ide, more details here
- deprecation:to suppress warnings relative to deprecation
- unchecked:to suppress warnings relative to unchecked operations
- fallthrough:to suppress warnings relative to missing breaks in switch statements
- cast: to suppress warnings relative to cast operations
- serial:to suppress warnings relative to missing serialVersionUID field for a serializable class
- finally:to suppress warnings relative to finally block that don’t retur
- unused: to suppress warnings relative to unused code and dead code
- all:to suppress all warnings
Meta-Annotations
Meta-Annotations are annotations which will be applied to other annotations. It’s just like meta-data. When you define your own annotation, you must use them. There are several meta-annotation types defined in java.lang.annotation
.
@Target
@Retention
@Documented
@Inherited
@Target
@Target
marks another annotation to **restrict what kind of Java elements the annotation can be applied to**. 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.
So annotation @Table can be used for class/interface/enum. @NoDBColumn can be used for field or property of a class.
@Retention
@Retention
specifies how the marked annotation is stored or could be considered as its lifecycle:
RetentionPolicy.SOURCE
– The annotation is retained only in the source level and is ignored by the compiler.RetentionPolicy.CLASS
– The annotation is retained by the compiler at compile time, but is ignored by the JVM.RetentionPolicy.RUNTIME
– The annotation is retained by the JVM so it can be used by the runtime environment.
So here, Column annotation is retained by the JVM at runtime, we could get its properties by java reflection to do some more operations!
Only if when we declare retention as RetentionPolicy.RUNTIME
, we could get the parameters of annotation by java reflection api to do some other operations.
@Documented
@Documented
indicates that whenever the specified annotation is used those elements should be documented using the Javadoc tool.
@Inherited
Inherited
indicates that the annotation type can be inherited from the super class. (This is not true by default.). If an annotation with @Inherited
is applied to a class, so all its subclasses will also have this annotation. For exemple: @Deprecated
Customize Annotations
The format to define an annotation:
When we use @interface
, it implements automatically java.lang.annotation.Annotation
interface. Every method in it is actually a configuration parameter. Name of the method is the name of the parameter, returnType is the type of argument(returnType can only be a basic type, Class, String, enum). You can declare the default value of the parameter.
It supports the following types:
- All basic types(int,float,boolean,byte,double,char,long,short)
- String
- Class
- enum
- Annotation
- All above in array
When we define an annotation, it can not inherit other annotations or interfaces. Only public or default is allowed for functions. If only one parameter, better to set the name as “value”. So we could ignore “value=” when use this annotation.
Example
Define now @MethodInfo
to indicate information about a method
So by its meta annotations, we could know that:
@Target(ElementType.METHOD)
-> It could only mark methods@Inherited
-> All the override functions in the subclasses will be added this annotations automatically@Retention(RetentionPolicy.RUNTIME)
-> So we could get the configuration parameters set in this annotations by java reflection api at runtime
Now we use this annotation on a method
Then we will use the Java reflection to parse @MethodInfo
in order to know information about the method marked by this annotation.
Output: