1:定义注解
package chapter20.one; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UseCase { public int id(); //注解元素 为 id public String description() default "no description"; //设置默认值, }
2:使用注解:
package chapter20.one; import java.util.List; public class PasswordUtils { //使用的注解内容看将会被注解处理器,取出并解析。spring中写不同的注解内容(提前定义好的),将会对应不同的处理结果 @UseCase(id=47,description="passwords must contain at least one numberic") public boolean validatePassword(String password){ return (password.matches("\w*\d\w*")); } @UseCase(id=48) public String encryptPassword(String password){ return new StringBuilder(password).reverse().toString(); } @UseCase(id=49,description="New passwords can't equal pre viously used ones") public boolean chenkForNewPassword(List<String> prePasswords,String password){ return !prePasswords.contains(password); } }
3:编写注解处理器
package chapter20.one; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * 注解处理器 * @author admin * */ public class UseCaseTracker { public static void trackUseCases(List<Integer> useCases,Class<?> cl){ for(Method m:cl.getDeclaredMethods()){ UseCase uc=m.getAnnotation(UseCase.class); //根据PasswordUtils中的方法,获取注解对象UseCase if(uc!=null){ System.out.println("found use case"+uc.id());//获取相应的注解内容 } useCases.remove(new Integer(uc.id())); } for(int i:useCases){ System.out.println("Warning :Missing use case -"+i); } } public static void main(String[] args) { List<Integer> useCases=new ArrayList<Integer>(); Collections.addAll(useCases, 47,48,49,50); trackUseCases(useCases, PasswordUtils.class); } }
4:测试结果
found use case49
found use case47
found use case48
Warning :Missing use case -50
5:讲解
java中元注解有四个: @Retention @Target @Document @Inherited;
@Retention:注解的保留位置
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target:注解的作用目标
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解