Preface:
In the previous article "Java annotation getting started", I introduced the definition and use of annotation in a wide range, but the depth is not enough. Therefore, after getting started with Java annotation, the author continues to sort out the concepts and knowledge points of annotation and share them with friends who like research.
Note: The Program Member or program element mentioned in this article is a concept that refers to the unit that makes up the program code, such as class, method, and member variable.
I. What is annotation?
Annotation provides a way to associate any information or metadata (metadata) with program elements. In some ways, annotation is like a modifier.
It is used in the declaration of packages, types, constructor methods, methods, member variables, parameters, and local variables. The information is stored in the "name = value" structure of annotation.
. Annotation is an interface that provides access to its information through the Java reflection API.
Annotation can be used to associate any information for a program element (class, method, member variable, etc. Note that there is a basic rule: annotaion is not
It can affect the execution of program code. No matter how much annotation is added or deleted, the code is always executed. In addition, although some annotation uses the Java reflection API method in
The Java interpreter ignores the annotation during runtime. Because the Java Virtual Machine ignores annotation
The annotation type does not work in the Code. Only through a supporting tool can the annotation type be accessed and processed. This article will cover the standard
Annotation and meta-annotation types. The tools that accompany these annotation types are Java compilers (of course, they must be processed in some special way ).
).
For the above reasons, annotation is very easy to use. A local variable can be labeled by an annotation type named nonnull as a local variable.
Variables cannot be assertion with null values. We can compile an annotation code analysis tool to parse the Code with the preceding variables and try to verify the code.
This asserted. Of course, you do not have to write the code yourself. After JDK is installed, you can find the tool named "apt" in the JDK/bin directory. It provides a box for handling annotation.
Rack: It scans annotation in the source code after it is started, and calls our defined annotation processor to complete the work we want to complete (such as verifying the assertions in the previous example ).
Speaking of this, the powerful functions of annotation seem to replace tools such as XDoclet. As we go deeper, we will be more confident in this.
Note: For details, see the jsr250 specification:
Http://www.jcp.org/aboutJava/communityprocess/pfd/jsr250/
Ii. annotation definition:
This article introduces annotation-related technologies. We will see the standard annotation type of java5.0, which is the "Built-in" Class mentioned above.
They can be directly supported by javac. Fortunately, javac in Java Beta has added support for custom annotation.
1. Concepts and syntax of annotation:
First, the key concept is to understand that annotation is the annotation of information or metadata associated with a program element. It never affects Java program execution, but has an impact on auxiliary tools such as compiler warnings or document generators.
The following lists common annotation types. We should note the differences between annotation and annotation types:
A. annotation:
Annotation uses the new syntax brought about by java5.0, and its behavior is very similar to modifiers such as public and final. Each annotation has
Name and number of Members> = 0. Each annotation member has a name and a value called the name = Value Pair (like JavaBean 1
Example), name = value loads annotation information.
B. annotation type:
The annotation type defines the annotation name, type, and member default value. An annotation type can be said to be a special Java interface and its member
The variable is restricted, and the new syntax is required to declare the annotation type. When we access annotation through the Java reflection API, the returned value is
The annotation type interface object. By accessing this object, we can easily access its annotation member. The following sections will refer to
The Java. lang package contains three standard annotation types.
C. annotation member:
The annotation member is declared in the form of a non-parameter method in the annotation type. The method name and return value define the name and type of the member. There is a specific default here
Syntax: the default value of any annotation member can be declared: An Annotation can use the name = value pair as the annotation without defining the default value.
Of course, you can use the name = value pair to override the default values of other members. Some Approximation class inheritance features. The constructor of the parent class can be used as the default constructor of the subclass.
It can be overwritten by the quilt class.
D. Marker annotation type:
An annotation type without Member definition is called marker annotation. This annotation type only uses its own existence or not to provide us with information. For example, override.
E. Meta-annotation:
Meta-annotation is also called meta-Annotation. It is used to declare annotation-type annotation. Java5.0 provides
Standard meta-annotation type. The target and retention described below are meta-annotation.
F.tar get:
The target of annotation is a labeled program element. Target describes the range of objects modified by annotation: annotation can be used
Packages, types (class, interface, enumeration, annotation type), type members (methods, constructor, member variables, enumerated values), method parameters, and local variables (such
Loop variables, catch parameters ). In the annotation type declaration, target can be used to better clarify the object to be modified.
G. Retention:
The retention of annotation defines the retention duration of the annotation: Some annotation only appears in the source code and is discarded by the compiler;
Others are compiled in the class file; annotation compiled in the class file may be ignored by the virtual machine, while others will be read when the class is loaded (please note
Class execution is not affected because annotation and class are separated in use ). You can use this meta-annotation
The "Life Cycle" Limit of annotation.
H. Metadata:
Metadata is widely used in various computer development processes, so when we talk about metadata here, metadata usually refers to the information loaded by annotation or annotation itself.
2. Use standard annotation:
Java5.0 defines three standard annotation types in the Java. lang package:
A. Override:
Java. Lang. Override is a marker
Annotation type, which is used as the annotation method. It indicates that the labeled method overload the parent class method and plays the role of assertion. If we use this annotation in
When the method of the parent class method is not overwritten, the Java compiler will warn of a compilation error.
This annotaton is often used when we try to overwrite the parent class method and make sure that the method name is wrong.
The method of use is extremely simple: when using this annotation, you only need to add @ override before the modified method.
The following code uses @ override to modify a tostring method that attempts to overload the parent class, and there is a spelling error sample:
Listing 1:
@ Override
Public String tosting () {// note that the method name is incorrectly spelled
Return "[" + super. tostring () + "]";
}
B. deprecated:
Deprecated is also a marker.
Annotation. When a type or type member is modified with @ deprecated, the compiler does not encourage the labeled program element. In addition, this modifier has a certain"
Continuity: if we use this obsolete type or member in code by inheritance or overwriting, although the inherited or overwritten type or member is not declared
@ Deprecated, but the compiler still requires an alert.
It is worth noting that the annotation type @ deprecated is different from the @ deprecated tag in javadoc: the former is the Java compiler.
The latter is identified by the javadoc tool to generate documents (including descriptions of why Program Members are obsolete, how they should be disabled or replaced ).
In java5.0, the Java compiler still looks for the javadoc @ deprecated as in the previous version.
Tag, and use them to generate warning information. However, this situation will change in later versions. Now we should start to use @ deprecated to modify outdated methods instead
@ Deprecated javadoc tag.
Listing 2:
The following is a piece of code using @ deprecated:
/**
* Here is the @ deprecated declaration of javadoc.
* @ Deprecated no one has players for this format any more. Use VHS instead.
*/
@ Deprecated public class Betamax {...}
C. suppresswarnings:
@ Suppresswarnings is used to warn the compiler to initialize classes, methods, member variables, and variables. In java5.0, The javac compiler provided by Sun
The-xlint option is provided to enable the compiler to warn against valid program code, which in turn represents program errors. For example, when we use a generic
When the collection class does not provide its type, the compiler will prompt a warning of "unchecked warning.
Generally, when this happens, we need to find the code that generates the warning. If it really indicates an error, we need to correct it. For example, if the warning information indicates that the switch statement in our Code does not cover all possible cases, we should add a default case to avoid this warning.
Similarly, sometimes we cannot avoid this warning. For example, we use a generic that must interact with the old code of the non-generic.
This unchecked cannot be avoided when the collection class is used.
Warning. At this time, @ suppresswarning will be used. Add @ suppresswarnings before calling the method to tell the compiler to stop this
Method warning.
Suppresswarning is not a marker
Annotation. It has a member of the string [] type. The value of this Member is the forbidden warning name. Warning that the javac compiler is effective by the-xlint Option
The name is also valid for @ suppresswarings, And the compiler ignores unrecognized warning names.
The annotation syntax allows annotation names followed by parentheses. The name = value pairs separated by commas are used to assign values to annotation members:
Listing 3:
@SuppressWarnings(value={"unchecked","fallthrough"})
public void lintTrap() { /* sloppy method body omitted */ }
In this example, the suppresswarnings annotation type only defines a single member, so only one simple value = {...} is used as the name = value pair. Since the Member value is an array, braces are used to declare the array value.
Note: We can abbreviated annotation in the following cases: when annotation only has a single member and the member name is "value = ". In this case, you can save "value = ". For example, abbreviated suppresswarnings annotation:
Listing 4:
@SuppressWarnings({"unchecked","fallthrough"})
If the number of forbidden warnings declared by suppresswarnings is one, you can ignore the braces:
@SuppressWarnings("unchecked")
3. Annotation Syntax:
In the previous chapter, we can see the syntax for writing marker annotation and a single member annotation. The complete syntax is described as follows:
Annotation is composed of "@ + annotation type name + (name-value pairs separated by commas. The members can be in any order. If
The annotation type defines the default value of a member, so this member can be omitted. The member value must be a compilation constant, embedded annotation, or array.
Next we will define an annotation type named reviews, which has a Member Composed of the @ review annotation array. This @ Review
The annotation type has three members: "reviewer" is a string, "comment"
Is an optional string with default values, and "Grade" is a review. Grade Enumeration type value.
Listing 5:
@Reviews({ // Single-value annotation, so "value=" is omitted here
@Review(grade=Review.Grade.EXCELLENT,
reviewer="df"),
@Review(grade=Review.Grade.UNSATISFACTORY,
reviewer="eg",
comment="This method needs an @Override annotation")
})
Another important rule of annotation syntax is that no program member can have more than one annotation instance. For example, you can simply place multiple @ review annotation in a class. This is also the reason why the @ reviews annotation type array is defined in the above Code.
4. Annotation member type and value:
The annotation member must be a non-empty compile-time expression. The available Member types are: primitive type, String, class, enumerated type, annotation type, and arrays of the previous type.
The following defines an annotation type named uncheckedexceptions. Its members are an array of classes that extend the runtimeexception class.
Listing 6:
@UncheckedExceptions({
IllegalArgumentException.class, StringIndexOutOfBoundsException.class
})
5. Annotation goals:
Annotation is usually placed before the type definition and member definition. However, it also appears before package, method parameters, and local variables. Next, let's discuss some of these less commonly used methods:
Package annotation appears before the package declaration.
The following example package-info.java contains an optional javadoc comment without any public type definition.
Listing 7:
/**
* This package holds my custom annotation types.
*/
@com.davidflanagan.annotations.Author("David Flanagan")
package com.davidflanagan.annotations;
When the package-info.java file is compiled, it will generate a package-info.class named containing annotation (special interface) Declarations
Class. This interface has no members. Its name package-info is not a valid Java identifier, so it cannot be used in Java source code. This interface is simply regarded
A placeholder for package annotation.
Annotation used to modify method parameters, catch parameters, and local variables only appears in the modifier positions of these Program Members. The Java file format is not a local variable or
The catch parameter is stored in preparation for annotation, so these annotation are always kept at the source code level (Source
Retention); The method parameter annotation can be saved in the class file or saved to the runtime.
Finally, note that the enumeration type definition does not allow any modifier to modify its enumerated values.
6. Annotation and default values:
In annotation, a member without a default value must have a member value. How to understand how the default value is processed is a very important detail: the annotation type is defined
The member default value is stored in the class file and is not compiled into annotation. If the default value of an annotation member is changed
This change affects all Members who do not explicitly provide the member value in this type of annotation (that is, the member value of this Member is modified ). Even if the annotation type makes its member default
After the value is changed, annotation has never been re-compiled. This type of annotation (compiled before the change) is also affected.
Iii. Working Principle of annotation:
Annotation and reflection
In Java, the reflection API provided by Java. Lang. Reflect is expanded to read the annotation capability during runtime. Let's review what we mentioned earlier:
Annotation type is defined as Runtime
After retention, it is visible at runtime. When the class file is loaded, annotation stored in the class file will be read by the virtual machine. So
How does reflect help us access annotation in class?
The following describes the new features of Java. Lang. Reflect for annotation.
Java. Lang. Reflect. annotatedelement is an important interface, which represents a Program Member that provides the ability to query annotation. This interface is
Java. Lang. Package, java. Lang. Class, and indirectly implemented by method class, constructor class,
Java. Lang. reflect field class implementation. The method parameters in Annotation can be
Getparameterannotations () method.
The following code uses the isannotationpresent () method of the annotatedelement class to determine whether a method has the @ unstable annotation, so as to determine whether the method is stable:
Listing 8:
import java.lang.reflect.*;
Class c = WhizzBangClass.class;
Method m = c.getMethod("whizzy", int.class, int.class);
boolean unstable = m.isAnnotationPresent(Unstable.class);
The isannotationpresent () method is very useful for checking marker annotation, because marker
Annotation has no member variables, so we only need to know whether the class method uses annotation modification. When processing
In annotation, we use the getannotation () method to obtain annotation member information (member name, member value ). Here we see
Java
Annotation system: If annotation exists, the object implementing the corresponding annotation interface will be getannotation () method
Then, call the member method defined in the annotation type to conveniently obtain any member value.
In retrospect, if the annotation type is declared as runtime retention, we use the following code to access the member value of @ reviews annotation:
Listing 9:
Annotatedelement target = whizzbangclass. Class; // obtain the queried annotatedelement
// Query the @ reviews annotation information of annotatedelement
Reviews annotation = target. getannotation (reviews. Class );
// Because the @ reviews annotation type member is an array of the @ review annotation type,
// The review [] reviews are declared below to save the value member value of the @ reviews annotation type.
Review [] reviews = annotation. Value ();
// Query the member information of each @ review Annotation
For (review R: reviews ){
Review. Grade = R. grade ();
String reviewer = R. reviewer ();
String comment = R. Comment ();
System. Out. printf ("% s assigned a grade of % s and comment '% s' % N ",
Reviewer, grade, comment );
}
4. How to customize annotation?
1. Differences between annotation and interfaces:
Because the annotation type is an extraordinary interface, there are some differences between the two:
A. the annotation type uses the keyword @ interface instead of interface.
This keyword Declaration implies a message: it inherits the java. Lang. annotation. annotation interface, not an interface.
B. The annotation type and method definition are unique and restricted.
Methods of the annotation type must be declared as non-parameter and thrown without exceptions. These methods define annotation members: the method name is a member name, and the return value of the method is
Member type. The Return Value Type of the method must be the primitive type, class type, enumeration type, annotation type, or a one-dimensional array with one of the preceding types as elements.
After the method, you can use default and a default value to declare the default value of the member. null cannot be the default value of the member. This is similar to the method defined in non-annotation type.
Different.
The annotation type and its method cannot use the annotation type parameter or the member cannot be generic. Only methods whose return value type is class can use generic in the annotation type, because this method can use class conversion to convert various types to class.
C. The annotation type is similar to the interface type.
They can define constants and static member types (for example, enumeration type definition ). The annotation type can also be implemented or inherited as an interface.
2. instance:
Next, we will see how to define the annotation type example. It shows the annotation type declaration and the difference between @ interface and interface:
Listing 10:
Package com. David Flanagan. Annotations;
Import java. Lang. annotation .*;
/**
* Using annotation to describe the labeled members is unstable and needs to be modified
*/
@ Retention (retentionpolicy. runtime)
Public @ interface unstable {}
The following example defines only one member. By naming this member as value, we can easily use this annotation quick declaration method:
Listing 11:
/**
* Use the annotation definition of author to indicate the author of the Code in the program.
*/
Public @ interface author {
/** Return author name */
String Value ();
}
The following examples are more complex. The reviews annotation type has only one member, but the type of this Member is complex: The review
An array composed of annotation. Review
The annotation type has three members: the enumeration type member grade, the string type member reviewer that represents the review name, and the string type member with the default value.
Comment.
List 12:
Import java. Lang. annotation .*;
/**
* The reviews annotation type has only one member,
* However, the type of this Member is complex: An array composed of review Annotation
*/
@ Retention (retentionpolicy. runtime)
Public @ interface reviews {
Review [] value ();
}
/**
* The review annotation type has three members:
* Enumeration type members: grade,
* Reviewer, a string Member of the review name,
* Comment, a string member with the default value.
*/
Public @ interface review {
// Embedded Enumeration type
Public static Enum grade {excellent, satisfactory, unsatisfactory };
// The following method defines annotation members.
Grade ();
String reviewer ();
String comment () Default "";
}
Finally, we define an annotation method to list all unchecked exceptions in Class running (this is not necessarily an error as mentioned above ). This
The annotation type uses an array as a unique member. Each element in the array is an exception class. To enhance reporting on unchecked exceptions (these exceptions are thrown at runtime), we
You can restrict the exception types in the Code:
Listing 13:
public @interface UncheckedExceptions {
Class<? extends RuntimeException>[] value();
}
V. Meta-Annotation
Annotation types can be marked by themselves. Java5.0 defines four standard meta-annotation types, which are used to provide
Annotation type description. These types and their supported classes can be found in the Java. Lang. annotation package. For more information, see
Jdk5.0 manual.
1. Talk about target.
As the target of the meta-annotation type, it describes the type of the Program Member modified by annotation. When an annotation type does not exist
Target is treated as a normal annotation. When you modify a specific program member, it will play the role of its application, for example, override For Modifier
When the @ target meta-annotation is added, the compiler checks the annotation and removes the override of the modified error type.
The target meta-annotation type has a unique value as a member. The type of this Member is Java. Lang. annotation. elementtype [], and elementtype is the enumerated type of program members that can be labeled.
2. Retention usage
We mentioned retention at the beginning of the article, but we didn't explain it in detail. Retention describes whether annotation is discarded by the compiler or retained in the class
Whether the file is read by the VM when the class file is loaded. By default, annotation is saved in the class file,
It cannot be accessed by reflection. Retention has three values: source, class, and runtime. These values come from
The enumerated type value of Java. Lang. annotation. retentionpolicy.
The retention meta-annotation type has a unique value as a member. Its value comes from the enumeration type value of Java. Lang. annotation. retentionpolicy.
3. appsented
Documented is a meta-annotation type used to describe other types of annotation which should be used as a public API of the labeled Program Member. Therefore, it can be documented by tools such as javadoc.
Incluented is a marker Annotation with no members.
4. inherited
@ Inherited meta-annotation is also a marker
Annotation, which describes that a labeled type is inherited. If an annotation type modified by @ inherited is used for a class,
Then this annotation will be used as a subclass of this class.
Note: The @ inherited annotation type is inherited by the subclass of the labeled class. The class does not inherit annotation from the interface it implements, and the method does not inherit annotation from the method it loads.
It is worth thinking that when @ inherited
The annotation retention of the annotation type annotation is retentionpolicy. runtime, then the reflection API enhances the following
Commitment. If we use Java. Lang. reflect to query a @ inherited
During annotation-type annotation, the reflection code check expands: checks the class and its parent class until the specified annotation type is found,
Or you can reach the top layer of the class inheritance structure.
Vi. Summary:
This article covers almost all concepts and knowledge points of annotation, from Annotation definition, syntax to working principle, how to customize annotation,
Meta-annotation. There are also some supporting code snippets for reference. Although there are not many, they are concise and important. I think annotation can be used well.
The key is to use it. I hope this manual can help you make good use of annotation, which is also my greatest pleasure.
From: http://hi.baidu.com/sorc/blog/item/f13f7e8ddc1fb114b31bbacf.html