[Path to Java Development] (15) annotations
1. IntroductionAnnotation (also known as metadata) provides a formal method for us to add information to code. Annotations combine metadata with source code files to a certain extent, rather than being saved in external documents. It can provide complete information required to describe the program, which cannot be expressed in Java. Therefore, annotations allow us to store additional information about the program in a format that tests and verifies the compiler. Annotations can be used to generate descriptor files or even new class definitions. By using annotations, we can save the metadata in the Java source code and use the Annotation API to construct processing tools for our own annotations. Annotations can generate cleaner and easier-to-read code and compiler type checks. Annotation saves all the information at the actual source code level, instead of comment, which makes the code more concise and easy to maintain.2. annotation Classification
| Classification by operating mechanism |
Description |
| Source code annotation |
The annotation only exists in the source code and does not exist when compiled into the. class file. |
| Compile-time Annotation |
Annotations only exist in the source code and. class files (for example, @ override) |
| Runtime Annotation |
It also works in the running stage, and even affects the annotation of the running logic (for example, @ Autowired) |
3. built-in Annotations:(1) @ override indicates that the current method definition will overwrite the methods in the superclass. If you are not careful about spelling errors, or the method signature cannot be overwritten, the compiler will send an error message. (2) @ Deprecated if the programmer uses an element that is annotated with it, the compiler will issue a warning message. (3) @ SuppressWarnings disable improper compiler warning information (This annotation can also be used before java SE5, but it does not work if it is ignored)
4. Basic syntax4.1 Definition annotation we can see that the annotation definition is similar to the interface definition. In fact, like any other Java interface, annotations are also compiled into class files.
package com.qunar.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class Annotation { // Define the Description Annotation @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented // Use the @ interface keyword to define the Annotation public @interface Description{ // The Member is declared with no parameter or exception String desc(); String author(); // You can use the default keyword to specify a default value for a member. int age() default 18; } }In addition to the @ symbol, the @ Description definition is similar to an interface. Some metadata annotations are required for defining annotations, such as @ Target and @ Retention. @ Target is used to define where your annotation will be used (a method or a class ), @ Retention defines the level at which the annotation is available (on the source code, class files, or runtime. 4.2 annotation element annotation @ Description contains the int element age, and the String element desc and author. Annotation elements can be of the following types:
- All basic data types (int, float, boolean, etc)
- String
- Class
- Enum
- Annotation
- If you use other types of arrays of the above types, the compiler will report an error. Note: It is not allowed to use any packaging type, but because automatic packaging exists, this is not a limit. Annotations can also be used as element types, that is, annotations can be nested.
4.3 The default value limits the compiler to be overly picky about the default value of elements. First, the element cannot have uncertain values, that is, the element must either have a default value or provide the value of the element when using annotations. Secondly, for elements of non-basic types, null cannot be used as the value when the source code is declared, or when the default value is defined in the annotation interface. For this constraint, we can only define some special values, such as null strings or negative numbers, to indicate that an element does not exist. 4.4 yuan annotation is only responsible for annotation of other annotations.
| Meta Annotation |
Parameters |
Description |
@ Taget
|
CONSTRUCTOR |
Constructor Declaration |
Indicates where the annotation can be used
|
| FIELD |
Domain Declaration |
| METHOD |
Method Declaration |
| PACKAGE |
Package Declaration |
| PARAMETER |
Parameter Declaration |
| TYPE |
Class, interface or enum Declaration |
| LOCAL_VARIABLE |
Local variable Declaration |
|
@ Retention |
SOURCE |
The annotation only exists in the source code and does not exist when compiled into the. class file. |
Indicates the level at which the annotation information needs to be saved |
| CLASS |
The annotation will only exist in the. class file and will be discarded by the VM. |
| RUNTIME |
The VM will retain annotations during runtime, so the annotation information can be read through the reflection mechanism. |
| @ Document |
|
|
Include this annotation in Javadoc |
| @ Inherited |
|
|
Allow subclass to inherit the annotation in the parent class |
4.5 Use annotation Syntax: @ <annotation Name> (<member name 1 >=< member value 1>, <member name 2 >=< member value 2> ,...)
package com.qunar.annotation; import com.qunar.annotation.Annotation.Description; public class Student { private String name; @Description(desc = "set name for student object" , author = "sjf0115") public String getName() { return name; } @Description(desc = "get name from student object" , author = "sjf0115", time = "2016-01-11") public void setName(String name) { this.name = name; } } 5. parse AnnotationThe reflection mechanism is used to obtain the runtime annotation information of classes, functions, or members, so as to dynamically control the running logic.
package com.qunar.annotation; import java.lang.reflect.Method; import com.qunar.annotation.Annotation.Description; public class ParseAnnotation { public static void main(String[] args){ Class class1 = null; try { // Use the class loader to load the class class1 = Class.forName("com.qunar.annotation.Student"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Determine whether the Description annotation exists in the Student class. boolean isExits = class1.isAnnotationPresent(Description.class); if(isExits){ // Annotation instance Description desc = class1.getAnnotation(Description.class); System. out. println ("annotation:" + desc. toString ()); }//if // Obtain all methods in the Student Class Method[] methods = class1.getMethods(); // Traverse all methods for (Method method : methods) { // Determine whether there is a Description annotation in the Method isExits = method.isAnnotationPresent(Description.class); if(isExits){ Description description = method.getAnnotation(Description.class); System. out. println ("method annotation:" + description. toString ()); }//if }//for } }Running result:
Method annotation: @ com. qunar. annotation. annotation $ Description (time = 2016-01-12, desc = set name for student object, author = sjf0115) method Annotation: @ com. qunar. annotation. annotation $ Description (time = 2016-01-11, desc = get name from student object, author = sjf0115) |
package com.qunar.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import com.qunar.annotation.Annotation.Description; public class ParseAnnotation { public static void main(String[] args){ Class class1 = null; try { // Use the class loader to load the class class1 = Class.forName("com.qunar.annotation.Student"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // Determine whether the Description annotation exists in the Student class. boolean isExits = class1.isAnnotationPresent(Description.class); if(isExits){ // Annotation instance Description desc = class1.getAnnotation(Description.class); System. out. println ("annotation:" + desc. toString ()); }//if // Obtain all methods in the Student Class Method[] methods = class1.getMethods(); // Traverse all methods for (Method method : methods) { // Obtain all annotations on the Method Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { if(annotation instanceof Description){ System. out. println ("Description annotation:" + annotation. toString ()); }//if }//for }//for } }Both programs use the reflection methods: getMethods () and getAnnotation (). They all belong to the AnnotatedElement interface (Class, Method, Field, and other classes implement this interface ). The getAnnotation () method returns the annotation object of the specified type, where Description is used. If the annotated method does not have an annotation of this type, the return value is null.