Thinking in Java 第20章 注解(元数据)

来源:互联网 发布:windows 8.1 激活 编辑:程序博客网 时间:2024/04/29 21:51

//声明:部分内容引自《Java编程思想(第四版)》机械工业出版社

– 定义在 java.lang 中的标准注解:

  • @Override,表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。

  • @Deprecated,如果程序员使用了注解为它的元素,那么编译器会发出警告信息。

  • @SuppressWarnings,关闭不当的编译器警告信息。

【基本语法】

– 定义注解。注解的定义看起来很像接口的定义。注解将会编译成 class 文件。例:

//: net/mindview/atunit/Test.java// The @Test tag.package net.mindview.atunit;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 Test {} ///:~

– 定义注解时,需要一些元注解
@Target 用来定义你的注解将应用于什么地方。
@Rectetion 用来定义该注解在哪一个级别可用,在源代码中(SOURCE)、类文件中(CLASS)或者运行时(RUNTIME)。

– 在注解中,一般都会包含一些元素以表示某些值。没有元素的注解称为标记注解

– 四种元注解。专门负责注解其他的注解。

  • @Target,表示该注解可以用在什么地方。

  • @Retention,表示需要在什么级别保存该注解信息。

  • @Documented,将此注解包含在 Javadoc 中。

  • @Inherited,允许子类继承父类中的注解。

【编写注解处理器】

– 使用注解的过程中,很重要的一个部分就是创建与使用注解处理器。例(读取 PasswordUtils 类):

package annotations;//: annotations/UseCaseTracker.javaimport java.lang.reflect.Method;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * Created by JT on 2016/7/28. */public class UseCaseTracker {    public static void trackUseCases(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(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);    }}

运行结果

这个程序用到了两个反射的方法:getDeclaredMethods() 和 getAnnotation(),它们都属于 AnnotatedElement 接口(Class、Method 与 Field 等类都实现了该接口)。getAnnotation() 方法返回指定类型的注解对象,在这里就是 UseCase。如果被注解的方法上没有该类型的注解,则返回 null 值。然后我们通过调用 id() 和 description() 方法从返回的 UseCase 对象中提取元素的值。其中,encriptPassword() 方法在注解的时候没有指定 description 的值,因此处理器在处理它对应的注解时,通过 description() 方法取得的是默认值 no description。

– 注解元素。
注解元素可使用的类型:

  • 所有基本类型

  • String

  • Class

  • enum

  • Annotation

  • 以上类型的数组

注解可以作为元素的类型,即注解可以嵌套。

– 默认值限制。
元素必须要么具有默认值,要么在使用注解时提供元素的值。
非基本类型的元素不可以以 null 作为其值,可以自己定义一些特殊值如字符串或负数,来表示某个元素不存在。

– 生成外部文件。

0 0
原创粉丝点击