Published on

Java编程思想读书笔记(七)第20章-注解

Authors
  • avatar
    Name
    Leon
    Twitter

  注解(也被称为**元数据**)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。

1 基本语法

  被注解的方法与其他的方法没有区别。注解可以与任何修饰符共同作用于方法,例如,public, static或void。从语法的角度来看,注解的使用方式几乎与修饰符的使用一模一样。

1.1 定义注解

  注解的定义看起来很像接口的定义。事实上,与其他任何Java接口一样,注解也将会编译成class文件

  定义注解时会需要一些元注解(meta-annotation),如@Target@Retention

  在注解中,一般都会包含一些元素以表示某些值。当分析处理注解时,程序或工具可以利用这些值。注解的元素看起来就像接口的方法,唯一的区别是你可以为其指定默认值。元素的类型有限制。

  没有元素的注解称为**标记注解(marker annotation)**。

  所有注解都继承了annotation

package net.mrliuli.annotations;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {} //(marker annotation)

1.2 三种标准注解和四种元注解

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

  • @Overrided
  • @Deprecated
  • @SuppressWarnings

  四种元注解:

  • @Target 表示该注解可以用于什么地方。
  • @Retension 表示需要在什么级别保存该注解信息。
  • @Documented 将此注解包含在Javadoc中。
  • @Inherited 允许子类继承父类中的注解。

1.3 关于注解

  • 注解元素的类型有限制,不可以是任意类型,使用除允许类型以外的类型编译器会报错。

  • 默认值限制:

    • 首先,元素不能有不确定的值。也就是说,元素必须要么具有默认值,要么在使用注解时提供元素的值。
    • 其次,对于非基本类型的元素,无论是在源代码中声明时,或是在注解接口中定义默认值时,都不能以null作为其值。这个约束使得注解处理器很难表现一个元素的存在或缺失的状态,因为在每个注解的声明中,所有的元素都存在,并且都具有相应的值。为了绕开这个约束,我们只能自己定义一些特殊的值例如空字符串或负数,以此表示某个元素不存在:
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface SimulationNull{
        public int id() default -1;
        public String description() default "";
    }
    
  • 生成外部文件。有些framework需要一些额外的信息才能与你的源代码协同工作,而这种情况最适合注解表现其价值了。像Enterprise JavaBean这样的技术,需要部署描述文件。Web Service、自定义标签库以及对象/关系映射工具(如Toplink和Hibernate)等,一般都需要XML描述文件,而这些描述文件脱离于源代码之外。

2 编写注解处理器

  使用注解的过程中,很重要的一部分就是创建与使用注解处理器用来读取注解

  • 反射机制的API可以构造注解处理器
  • 外部工具apt可以解析带有注解的Java源代码

参考文献:

  1. 《Java编程思想(第4版)》——(美)Bruce Eckel 著 陈昊鹏 译