Definition of annotations
Annotations are defined by @interface
public @interface Log { }
Its keywords and interface definitions are almost the same, except that there is one more. @ Symbols
Application of Annotations
Annotations can be used simply by adding @xx to the top of a class or method.
public class Controller { @Log public void test(){ } } @Log public class Controller { public void test(){ } }
meta annotation
Meta-annotations: Annotations that define annotations are basic annotations that can be defined on annotations.
@Retention
Used to illustrate the life cycle of annotations
-
@ Retention (Retention Policy. SOURCE) annotations are retained only in the source phase, and are discarded at compile time.
-
@ Retention (Retention Policy. CLASS) default policy, where annotations are reserved only for compilation and are not loaded into the JVM.
-
@ Retention (Retention Policy. RUNTIME) annotations can be retained until the program runs, and it will be loaded into the JVM, so it can also be retrieved when the program runs.
@Documented
Documented annotations indicate that this annotation is recorded by javadoc, and by default there are similar logging tools. If a type declaration is annotated and documented, its annotations become part of the public API.
@ Target explains the purpose of annotations
-
@ Target(ElementType.TYPE) interface, class, enumeration, annotation
-
@ Target(ElementType.FIELD) field, enumeration constants
-
@ Target(ElementType.METHOD) method
-
@ Target(ElementType.PARAMETER) method parameters
-
@ Target(ElementType.CONSTRUCTOR) constructor
-
@ Target(ElementType.LOCAL_VARIABLE) local variable
-
@ Target(ElementType.ANNOTATION_TYPE) Annotation
-
@ Target(ElementType.PACKAGE) package
@Inherited
@ Inherited: If an annotation 1 that uses this annotation is used by a class, then this annotation 1 also takes effect on a subclass of the class. For example:
@Inherited @Target(ElementType.METHOD) public @interface Log { } @Log public class testA(){} public class testB() extends testA{}
TesA applies the @Log annotation, and testB has the @Log annotation on it.
@Repeatable
For example:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Logs { Log[] value(); } @Repeatable(Logs.class) public @interface Log{ String descr() default ""; } public class Controller { @Log(descr="Description 1") @Log(descr="Description 2") public void test(){ } } public class LogRunner { public static void main(String []args) throws Exception{ System.out.println("Start time:"+new Date()); Class classs=Controller.class; Method[] ms=classs.getMethods(); for(Method method:ms){ boolean flag=method.isAnnotationPresent(Logs.class); if(flag){ Logs logs=method.getAnnotation(Logs.class); for(Log log:logs.value()){ System.out.println(log.descr()); } } } } }
When output, it will output, describing 1, describing 2.
Implementing custom annotations
The first step is to define an annotation
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface Log { String methodName() default "defaultAMethod"; String controller() default "defaultController"; String descr() default "defaultDescr"; }
The second step is to apply this annotation
public class Controller { @Log public void test(){ System.out.println("Ending time:"+new Date()); } }
The third step is to make this annotation work by reflection.
public class LogRunner { public static void main(String []args) throws Exception{ System.out.println("Start time:"+new Date()); Class classs=Controller.class; Method[] ms=classs.getMethods(); for(Method method:ms){ boolean flag=method.isAnnotationPresent(Log.class); if(flag){ Log log=method.getAnnotation(Log.class); System.out.println(log.methodName()); System.out.println(log.descr()); System.out.println(log.controller()); method.invoke(classs.newInstance(),null); } } } }
Output results
If the comment above the second step method does not use the default value, change the code to
public class Controller { @Log(methodName = "test",controller = "testController",descr = "test") public void test(){ System.out.println("Ending time:"+new Date()); } }
Then it will output