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

//声明:部分内容引自《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.java

import 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值