Learn how to develop a custom annotation today. To make annotation meaningful, you also need to borrow the reflection mechanism that you learned the previous few days.
Let's start today's study.
The annotation definition format. It is similar to creating a new interface class file, but in order to differentiate it, we need to declare it as @interface
Public @interface annotation Name {
Data type variable name ();
}
The following declares a annotation
Public @interface myannotation { }
Use this annotation
@MyAnnotationpublic class annotationdemo{public static void main (String []args) { }}
Note that the above annotation has no parameters, so it doesn't make any sense. To make it meaningful, you need to borrow the Java reflection mechanism.
Annotation with content
Public @interface myannotation { public String value ();}
When you define a annotation parameter, you must clearly indicate the contents of the variable when you use it.
@MyAnnotation ("Annotation") public class annotationdemo{public static void main (String []args) { }}
or explicitly assigned to value
@MyAnnotation (value= "Annotation") public class annotationdemo{public static void main (String [] args) { }}
You can set a parameter, or you can set multiple parameters.
Public @interface myannotation { public String key (); Public String value ();
When used, pass in the parameters to be received.
@MyAnnotation (key= "key", value= "Annotation") public class annotationdemo{public static void Main (String []args) { }}
You can also pass multiple values for one parameter.
Public string[] Value (); Received in an array form. value={"Annotation", "Java"}
I'm sure everyone is just like me. This custom annotation does not define a private domain value, public string[] value () is a function, then how does it receive the value? Keep on learning with this question.
All of the above annotation must be in use, given the parameters. Can you set the default parameters and use the default values? The answer is yes.
public @Interface myannotation { publicdefault "Java"; // The default value is specified well Public default "Annotation"; // The default value is specified }
In the operation, sometimes the parameters in the annotation fixed its value range, can only take a fixed number of values, this time, the need for the enumeration in Java.
public @Interface myannotation { publicdefault color.black; // The default value is specified well Public default Color.Blue; // The default value is specified well // when using annotation externally, you also need to fix the values in the enumeration Public enum color{ RED, BLUE, BLACK }}
External
// when using annotation externally, you also need to use the values in the enumeration @MyAnnotation (key=color.red)publicclass annotationdemo{ publicstaticvoid main (String []args) { }}
The above is a simple definition and use of custom annotations.
In annotation, you can use retention to define a annotation's save scope.
@Documented @retention (value=retentionpolicy.runtime) @Target (value=Elementtype.annotation_type) Public@Interfacemyannotation { PublicColor Key ()defaultColor.Black;//The default value is specified well PublicColor[] Value ()defaultColor.Blue;//The default value is specified well//when using annotation externally, you also need to fix the values in the enumeration Public enumcolor{RED, BLUE, BLACK}}
1, @Documented class and method annotation by default is not present in the Javadoc, in order to add this property use @documented
2. @Retention
The scope of the annotation is specified by Retentionpolicy, and the Retentionpolicy has three ranges:
Retentionpolicy.source//This annotation type of information will only be stored in the program's original file (*.java), after compilation will not be saved in the compiled file (*.class)
Retentionpolicy.class//This annotation type of information will be stored in the program's original file (*.java), after compilation will be saved in the compiled file (*.class), However, these annotation information will not be loaded into the JVM virtual machine at the time of execution, if a annotation does not specify a range, the default is this range
Retentionpolicy.runtime//As the name implies, these annotation type information will be persisted to execution and loaded into the JVM virtual.
In these three areas, the most important thing we need to be concerned about is retentionpolicy.runtime, because it will work at the time of execution.
What is the scope of the three types of annotation that are built into the system mentioned in the previous article?
@retention (Value=retentionpolicy.source) is used when defining @Override.
@retention (value=retentionpolicy.runtime) is used when defining @Deprecated.
@retention (Value=retentionpolicy.source) is used when defining @SuppressWarnings.
3. @Target
@Target annotations indicate which targets an annotation is applied to, and can be selected as follows, depending on the English name, I believe you can read it.
Elementtype.type (class, Interface, enum)
Elementtype.field (instance variable)
Elementtype.method
Elementtype.parameter
Elementtype.constructor
Elementtype.local_variable
Elementtype.annotation_type (applied to another annotation)
Elementtype.package
4. @Inherited
@Inherited indicates whether a parent class that uses a annotation can have this annotation applied to subclasses.
The sample code is as follows, defining @inherited
Importjava.lang.annotation.Documented;ImportJava.lang.annotation.ElementType;Importjava.lang.annotation.Inherited;Importjava.lang.annotation.Retention;ImportJava.lang.annotation.RetentionPolicy;Importjava.lang.annotation.Target; @Documented @retention (Value=retentionpolicy.runtime)//must be specified as runtime, otherwise it will not work@Target ({elementtype.type,elementtype.method, Elementtype.constructor,elementtype.annotation_type, Elementtype.package}) @Inherited Public@Interfacemyannotation { PublicString key (); PublicString value (); }
Note information that is defined in the parent class can still be obtained in the Stu subclass.
Interfacea{ PublicString SayHello ();} @MyAnnotation (Key= "Key", value= "value")classPerImplementsa{ PublicString SayHello () {return"Hello World"; }}classStuextendsper{ PublicString SayHello () {return"Hello World"; }} Public classannotationdemo{ Public Static voidMain (String []args) {Class<?> C =NULL ; C=NewStu (). GetClass (); if(C.isannotationpresent (myannotation.class)){//determines whether the specified annotation isMyannotation MDA =NULL ; MDA= C.getannotation (myannotation.class) ;//get the specified annotationString key = Mda.key ();//Remove the Set keyString value = Mda.value ();//Remove the value of the settingSystem.out.println ("key =" +key); System.out.println ("VALUE =" +value); } }}
Here's what I'm most concerned about, how to use reflection to get comment information at run time.
Reflection and annotation
For a annotation to become meaningful, it is necessary to combine the reflection mechanism. In class, it is like a annotation-related method.
Public <a extends annotation> A getannotation (class<a> annotationclass)//If an element has a comment, get all its comments
Public annotation[] Getannotations ()//Returns all comments on this element
Public <a extends annotation> A getdeclaredannotation (class<a> annotationclass)//Return all comments placed directly on this element
public boolean isannotation () //Determines whether an element represents a comment
public boolean isannotationpresent (class<? extends annotation> Annotationclass)//Determine if a comment exists on an element
Wait a minute......
The following code shows how to get annotation through reflection
Importjava.lang.annotation.Annotation;ImportJava.lang.reflect.Method;Interfacea{ PublicString SayHello ();}classPerImplementsa{@SuppressWarnings ("Unchecked") @Override @Deprecated//only it works at run time PublicString SayHello () {return"Hello World"; }} Public classannotationdemo{ Public Static voidMain (String []args) {Class<?> C =NULL ; C=NewPer (). GetClass (); Method ToM=NULL; Try{ToM= C.getmethod ("SayHello");//Find the SayHello () method}Catch(nosuchmethodexception e) {//TODO auto-generated Catch blockE.printstacktrace (); } Catch(SecurityException e) {//TODO auto-generated Catch blockE.printstacktrace (); } Annotation an[]= Tom.getannotations ();//get all the annotation for(Annotation A:an) {//using the foreach outputSystem.out.println (a); } }}
The output is @java.lang.deprecated (), which is obvious, as mentioned earlier, and only @deprecated is valid at run time .
So to make our custom annotation valid at runtime, we must specify retentionpolicy.runtime at the time of definition.
How to get the value in the defined comment information.
At the time of definition
Importjava.lang.annotation.Documented;ImportJava.lang.annotation.ElementType;Importjava.lang.annotation.Retention;ImportJava.lang.annotation.RetentionPolicy;Importjava.lang.annotation.Target; @Documented @retention (Value=retentionpolicy.runtime)//must be specified as runtime, otherwise it will not work@Target (value=Elementtype.method) Public@Interfacemyannotation { PublicString key (); PublicString value (); }
Remove the value from the comment message
ImportJava.lang.reflect.Method;Interfacea{ PublicString SayHello ();}classPerImplementsa{@MyAnnotation (Key= "Key", value= "value") PublicString SayHello () {return"Hello World"; }} Public classannotationdemo{ Public Static voidMain (String []args) {Class<?> C =NULL ; C=NewPer (). GetClass (); Method ToM=NULL; Try{ToM= C.getmethod ("SayHello"); } Catch(nosuchmethodexception e) {//TODO auto-generated Catch blockE.printstacktrace (); } Catch(SecurityException e) {//TODO auto-generated Catch blockE.printstacktrace (); } if(Tom.isannotationpresent (myannotation.class)){ //determines whether the specified annotation isMyannotation MDA =NULL ; MDA= Tom.getannotation (myannotation.class) ;//get the specified annotationString key = Mda.key ();//Remove the Set keyString value = Mda.value ();//Remove the value of the settingSystem.out.println ("key =" +key); System.out.println ("VALUE =" +value); } }}
The above code can be used to remove the value in the comment information.
Summarize
Annotation in use, it must be a combination of reflection, set some content into the method to complete the specific function.
Annotation in Java (ii, custom annotation)