+4.3编写注解处理器
如下根据Java反射写出的一个简单的测试用例处理器
/* ***************************************************************************** * This software is under the Apache License Version 2.0 * Author: Tao - mail:cn.java.river@gmail.com * Spreading Your Heart **************************************************************************** */ package atao.annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * 用例检测的注解处理器 * * @author Tao * @since 1.0 */ public class UseCaseChecker { public static void trackUseCases (ListuseCases, Class cl) { for (Method m : cl.getDeclaredMethods ()) { UseCase uc = m.getAnnotation (UseCase.class); if (uc != null) { System.out.println ("找到用例:" + uc.id () + " " + uc.description ()); useCases.remove (new Integer (uc.id ())); } } for (int i : useCases) { System.out.println ("警告-- 缺失用例:" + i); } } public static void main (String[] args) { List useCases = new ArrayList (); Collections.addAll (useCases, 1, 2, 3, 4,5); trackUseCases (useCases, PasswordUtils.class); } } /**运行输出结果为: 找到用例:1 密码必须包含至少一个数字 找到用例:4 新密码不能和曾经用过的密码重复 找到用例:3 无描述 警告-- 缺失用例:2 警告-- 缺失用例:5 */
至此,一个简单的Java注解使用流程我们已经走完,接下来我们谈谈注解的语言要素和相关Java API等.
+5语言要素
+5.1元注解
至JDk7,Java提供了3种内置标准注解(@Override,@Deprecate,@SuppressWarnings)和四种元注解(@Target,@Retention,@Documented,@Inherited)。细心的人会发现这些在上文叙述中已经提到。
@Retention,标示注解的生命周期,其用RetentionPolicy枚举参数。包含三个(RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME)。SOURCE,RUNTIME除前文代码中已经做出解释。至于CLASS表示注解会保存在class文件中,类加载时将被丢弃。事实上Java在其J2EE规范的API中已经广泛的使用了注解机制,但是通过文件查找工具确认JDK(j2se/j2ee)至1.7结束都没有提供可供参考的RetentionPolicy.CLASS生命周期的注解。这或许也预示着CLASSS生命周期的定义或许是一堆废柴。@Documented,是包含在JavaDoc中@Inherited,允许子类继承父类的注解
+5.2默认参数
当注解定义只包含一个字符串参数时,使用如下方式可以使用直接的字符串填充方式为参数赋值
//定义
@interface SimpleUseCase{String value();}
//使用
@SimpleUseCase("就是这样么简单,可不使用键值对赋值")
+5.3裸体的注解
如上例中裸体注解@Nacked,将默认使用@Target(所有的ElementType类型),@Retention(RetentionPolicy.CLASS).参见此处或Java Retention源代码中的解释。+5.4可重复注解
从JDK8开始java提供了一种允许自修饰的可循环注解@Repeatable,注解定义使用了此注解修饰则允许在目标上连续多次使用本注解。注意请下载JDK8,以下代码方可编译。
@Repeatable(Schedules.class)
public @interface Schedule {
String dayOfMonth();
String dayOfWeek();
String hour();
}
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { /**方法体*/ }