- Annotations are one of the most important language changes introduced into Java SE5.
- The Java1.6 contains three standard annotations and four meta annotations (meta annotations are dedicated to annotating other annotations).
- Most of the time we define our own annotations and write our own processors to handle them.
- @Target (Elementtype.method)
Packagejava.lang.annotation;/** * @authorJoshua Bloch *@since1.5 * @jls 9.6.4.1 @Target * @jls 4.1 The kinds of Types and Values*/ Public enumElementType {/**Class, interface (including annotation type), or enum declaration*/TYPE,/**Field declaration (includes enum constants)*/FIELD,/**Method Declaration*/METHOD,/**formal parameter declaration*/PARAMETER,/**Constructor Declaration*/CONSTRUCTOR,/**Local Variable Declaration*/local_variable,/**Annotation Type declaration*/Annotation_type,/**Package Declaration*/Package ,/*** Type Parameter declaration * *@since1.8*/Type_parameter,/*** Use of a type * *@since1.8*/Type_use}
View Code
- @Retention (Retentionpolicy.runtime)
Packagejava.lang.annotation;/** * @authorJoshua Bloch *@since1.5*/ Public enumRetentionpolicy {/*** Annotations is to being discarded by the compiler. */SOURCE,/*** Annotations is to being recorded in the class file by the compiler * and need not being retained by the VM at RU N Time. This is the default * behavior. */CLASS,/*** Annotations is to being recorded in the class file by the compiler and * retained by the VM at run time, so They may be read reflectively. * * @seejava.lang.reflect.AnnotatedElement*/RUNTIME}
View Code
@Target (Elementtype.method) @Retention (retentionpolicy.runtime) public @Interface usecase { publicint ID (); Public default "No description";}
Public classpasswordutils {@UseCase (id= Description = "Passwords must contain at least one numeric") Public BooleanValidatePassword (String password) {return(Password.matches ("\\w*\\d\\w*")); } @UseCase (ID= 48) Publicstring Encryptpassword (string password) {return NewStringBuilder (password). reverse (). toString (); } @UseCase (ID= $, Description = "New passwords can ' t equal previously used ones") Public BooleanCheckfornewpassword (List<String>prevpasswords, String password) { return!prevpasswords.contains (password); }}
- Writing the annotation processor
Public classUsecasetracker { Public Static voidTrackusecases (list<integer> usecases, class<?>cl) { for(Method m:cl.getdeclaredmethods ()) {UseCase UC= M.getannotation (usecase.class); if(UC! =NULL) {System.out.println ("Found use case:" + uc.id () + "" +uc.description ()); Usecases.remove (NewInteger (Uc.id ())); } } for(inti:usecases) {System.out.println ("Warning:missing use case-" +i); } } Public Static voidMain (string[] args) {List<Integer> usecases =NewArraylist<integer>(); Collections.addall (usecases,47, 48, 49, 50); Trackusecases (Usecases, passwordutils.class); }}
Found use case:47-50
A few points to note:
The label @usecase is defined by Usecase.java, which includes an int element ID, and a string element description.
The annotation elements are available in the following types (otherwise the compiler will error):
- All basic types (int, float, Boolean, etc.)
- String
- Class
- Enum
- Annotation
- Arrays of the above types
The annotation element must either have a default value or provide the value of the element when using annotations.
Annotations do not support inheritance. (See Thinking in Java fourth Edition 20.2.4)
Reference:
- Thinking in Java Fourth Edition (Bruce Eckel)
01. Learn @interface in Java