今天这章节来讲讲Java里面的注解。

1. 基本概念

注解是JDK1.5引入的一个Java语言新特性。注解与接口很相似,它与类、接口、枚举是同一层次,它们都称为Java的一个类型(TYPE)。

注解:也称为元数据,为我们提供了程序代码的描述信息,而这些描述信息并不属于程序本身。注解并不直接影响其注释的代码的工作。是为了方便在后面某个时刻非常方便的使用这些数据。

注解:是一个包含注解类型和零或多个K-V对的Java修饰符。每中每个K-V对都绑定了一个不同的注解类型值。注解的目标简单的说就是绑定信息到其标注的编程元素。

注解的用途:

1)为编译器提供信息:注解可以被编译器用来检测错误与警告。像@Override这样的

2)编译时和部署时附加操作:比如说生成说明文档。

3)运行时操作:

像Junit从4.X开始使用注解简化测试代码和流程

Spring也会使用注解做XML配置管理的一种配合或替代

有些工具根据特定的注解做代码分析等

注解可以减少、美化代码,或为现有代码增加额外功能等。

4. 语法

注解的定义和接口定义相似,又有些不同。如:

无参注解

@Documented         // 此注解包含在Javadoc中
@Retention(RetentionPolicy.RUNTIME) // VM运行期仍保留该注解,可通过反射获得
// 此注解适用的目标(构造方法、字段、本地变量、方法、包、参数、类型)
@Target(value = {ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.LOCAL_VARIABLE,ElementType.METHOD,ElementType.PACKAGE,ElementType.TYPE})
public @interface Deprecated {
    // Deprecated 为注解名称
}

含参数注解

@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)  // 注解仅保留在Java源文件中
public @interface SuppressWarnings {
    // 支持的参数列表all,deprecation,unchecked,path,finally等
    String[] value();
}

自定义注解

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserCase {
    //  测试用例编号
    public int id();

    /***
     * 测试用例描述
     * @return
     */
    public String description() default "no desc";
}


最简单的注解

@interface Naked{}

允许子类继承父类的注解

@Inherited
public @interface TrustFather {
}

总结:

1、主题声明,权限修饰符 + @interface +  注解名称

2、注解描述

适用目标:@Target

保留级别:@Retention

是否产生JavaDoc: @Documented

允许子类继承父类的注解:@Inherited

其他注解

####以上我们是定义了注解,再看下要如何使用注解######

public class PasswordUtils {
    @UserCase(id = 47, description = "密码必须至少有一个数")
    public boolean validatePassword(String password) {
        return password.matches("\\w*\\d\\w*");
    }

    @Deprecated
    public void deprecatedMethod() {}

    @SuppressWarnings({"unused", "rawtypes"})
    public void unsafeMethod() {
        List unsafeList = new ArrayList<String>();
    }
}



如何让注解执行起来呢

public class UseCaseChecked {

    public static void trackUseCases(List<Integer> useCases,Class<?> cl){
        for (Method m:cl.getDeclaredMethods()
             ) {
            UserCase uc = m.getAnnotation(UserCase.class);
            if (uc!=null){
                System.out.println("找到了一个用例:"+uc.id()+" " + uc.description());
                useCases.remove(new Integer(uc.id()));
            }
        }

        for (int i:useCases
             ) {
            System.out.println("warn-没有用例:"+i);
        }
    }

    public static void main(String[] args) {
        List<Integer> useCases = new ArrayList<Integer>();
        Collections.addAll(useCases,1,2,47);
        trackUseCases(useCases,PasswordUtils.class);
    }
}



以上通过反射的方式访问注解。

比如可以在这样用。定义在controller层上面的注解。然后在全局拦截器里面配置拦截。获取到是否有这样的注解。