Java注解编程指南(二)

2014-11-24 00:57:53 · 作者: · 浏览: 1
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 = "新密码不能和曾经用过的密码重复") public boolean checkForNewPassword (List prevPasswords, String password) { return !prevPasswords.contains (password); } /**@deprecated 楼主决定不推荐使用此方法了,自己随便找个个其他的试试吧.*/ @Deprecated public void deprecatedMethod(){} @SuppressWarnings ({ "unused", "rawtypes" }) public void unsafeMethod () { //@SuppressWarnings ({ "unused", "rawtypes" }) //用在这里仍然可以,因为此注解支持修饰类和本地变量等类型。 List unsafeList = new ArrayList (); } }

+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 (List 
  
    useCases, 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)。细心的人会发现这些在上文叙述中已经提到。

@Target,标示该注解可用在什么地方。可用参数包括(构造方法、字段、本地变量、方法、包、参数、类型(类、接口、注解、枚举))。其用ElementType枚举参数,读者可到阅读ElementType枚举产看原版解释。
@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() { /**方法体*/ }

+6注解工具APT

APT全称 Annotation Processing Tool。注意:APT工具及com.sun.mirror包中相关的API自Java SE 7已