I wrote a Java annotation article before, but I didn’t have much understanding of annotation application at that time, and some knowledge points were not fully understood. I recently looked at the Retrofit source code to further understand the use of annotations. This article is a review of the previous knowledge and a supplementary explanation of the use of annotations.
What are annotations for
Annotations are like tags that mark your code, and can be understood as special modifiers that apply to classes, methods, parameters, variables, constructors, and packages.
I understand the role of annotations, generally have the following three applications
1. Provide information to the compiler: The compiler can use annotations to detect errors and warnings
A typical example of this is the @Override annotation, which marks method overrides and is discarded during source compilation.
2. Compilation stage processing: Software tools can use annotation information to automatically generate code, HTML documents, and other corresponding processing
For example, annotations in the ButterKnife framework use compile-generated code (APT) techniques.
3. Runtime processing: Some annotations can receive code extraction while the program is running, providing a logical basis for the program to judge or logical processing basis
For example, @get and @Post annotations that are custom defined by the Retrofit framework are parsed while processing the request logic to implement the relevant request logic.
How to declare annotations
format
@ yuan notespublic @interfaceAnnotation name {attribute list;// No
}
Copy the code
nature
Annotations are at the same level as classes, interfaces, and enumerations.
Annotation is the nature of an inheritance. Java lang. The annotation. The annotation interface interface
attribute
-
Attribute declaration:
Attributes of annotations, also called member variables
Q: Since an annotation is essentially an interface, and we all know that interfaces cannot define member variables, what are the attributes of the annotation?
@Documented @Target(METHOD) @Retention(RUNTIME) public @interface GET { String value(a) default ""; } Copy the code
In Retrofit’s @GET example, we can see that the attribute of the annotation actually corresponds to the interface method. In annotations we call things like String value() properties. Obviously assigning to ‘attributes’ sounds a lot more palatable than assigning to methods.
A: The attributes of annotations are defined in the definition of annotations
No arguments method
The method name is the property name, and the return value is the type of the property.The attribute type of the annotation must be the following:
Eight basic types (Byte, Boolean, char, short, int, Long, float, double) and String, Enum, Class, annotation types, as well as arrays of these types
-
Attribute assignment
Attribute is assigned to
The attribute name = XXX
Multiple attributes are assigned to.
Separated.Attributes of annotations can be passed
default
The keyword specifies the default value. If a default value is specified, it can be used without assigning a value. Otherwise, the value must be explicitly assignedIf the annotation has only one property named
value
You can omit the attribute name when assigningTake the @get annotation above:
@GET(value = "1111") void testAssign2(a); // or omit value @GET("1111") void testAssign1(a); Copy the code
Yuan notes
Another very important concept for annotation declarations is the meta-annotation.
Meta-annotations are basic annotations that can be used to annotate other annotations; Think of it as a special modifier used to explain annotations.
Common meta-annotations are as follows:
-
@Retention
Description: Used to identify the lifetime of an annotation
Values:
public enum RetentionPolicy { /** * annotations are retained only at the source stage and discarded at compile time */ SOURCE, /** * annotations are kept in the Class file, but are discarded by the JVM at runtime */ CLASS, /** * annotations are retained in the Class file and are also retained at runtime RUNTIME } Copy the code
-
@Documented
Note: Used to indicate that annotations can be used as public apis that can be extracted into documentation by tools such as Javadoc. @documented is just a marker, no attribute.
-
@Target
Description: Used to restrict the application scenario of the current annotation (class, method, etc.), default is not restricted if not used.
@Target
The array type is array, so multiple values are assigned at the same time.In {}, multiple values are separated by commas. If only one value is assigned, {} can be omitted.
Example:
@Target({METHOD, PARAMETER, FIELD}) public @interface FontRes { } Copy the code
Values:
public enum ElementType { /** class, interface (including annotations), enumeration */ TYPE, /** attributes (including enumeration constants) */ FIELD, / * / * * method METHOD, /** Method argument */ PARAMETER, /** constructor */ CONSTRUCTOR, /** Local variable */ LOCAL_VARIABLE, / * comment * / ANNOTATION_TYPE, / * * * / PACKAGE, /** ** is used for type parameter declarations. Java8 adds */ TYPE_PARAMETER, /** ** where types are used, Java8 adds */ TYPE_USE } Copy the code
-
@Inherited
Description: allows subclasses to inherit the current annotation. If a superclass is decorated with the current annotation, its subclasses also have the annotation. @interited has no attribute value.
Note: A class cannot inherit annotations from the interface it implements, nor can a method inherit annotations from the method it overloads
-
@Repeatble
Used to mark the current annotation can be repeated, java1.8 new feature. This can be done with @REPEATable if the same annotation needs to be used multiple times in the same scenario
Example:
/** Custom container annotation Roles(used to hold other annotations, must have a value attribute in it@RepeatableAnnotated array of annotations) */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Roles { Role[] value(); } /** Custom annotation Role, use@RepeatableAnnotations, so that the Role annotation can be used multiple times */ @Repeatable(Roles.class) public @interface Role { String role(a) default ""; } // An example @Role(role="husband") @Role(role="father") @Role(role="son") public class Person {}Copy the code
How to use annotations
By use, I mean not just the use of simple meanings, but also the reading of annotations, giving them real meaning
Notes are divided into:
-
Built-in JDK annotations such as @Override, @deprecated, and so on are read and processed by the compiler to implement what they actually represent
-
Annotations provided by third-party frameworks, such as @get, @Post, etc. from Retrofit, will be read and processed to give them real meaning
-
Custom annotations: These are the kind of annotations we need to read ourselves to give them real meaning. Otherwise there is no point in declaring annotations and using them in the context (methods, parameters, etc.).
There are two ways to extract and use custom annotations
-
Scan and process annotations (APT, Annotation Processing Tool) at compile time. For details, see Java Annotation application
-
The runtime scans and processes annotations (via Java reflection related apis). Take a look at Retrofit’s use of runtime annotations, and consider writing an example later on.