何为注解
- 注解(也被称为元数据),它为我们在代码中添加信息提供了一种形式化的方法,使我们可以在某个时刻非常方便地使用这些数据。它使得我i们能够以将由编译器来测试和验证的格式,存储有关程序的额外信息,它可以用来生成描述符文件,甚至可以是新的类定义,这样有助于减轻编写“样板”代码的负担。
- 通过注解我们可以将这些元数据保存在Java源代码中,同时,注解的优点还包括:更加干净易读的代码以及编译器类型检查等。我们还可以自定义注解,并按自己的方式使用它们。
内置的注解
- 在JavaSE中内置了三种java.lang包下的注解:
- @Override:表示当前的方法定义将覆盖超类中的方法
- @Deprecated:表示发出警告信息
- @SuppressWarnings:关闭不当的编译器警告信息
- Java还另外提供了四种注解,专门负责新注解的创建
注解的基本语法
基本注解
- 下面就是一个简单的注解的定义,可以看到注解的定义很像接口的定义,但注解使用的是
@interface
来定义的,与其他的Java接口一样,注解也会被编译成class文件
1 | (ElementType.METHOD) |
- 在定义注解时,需要一些
元注解
,如@Target
和@Retention
,@Target
表示定义好的注解将会被应用在什么地方;@Retention
则表示该注解在哪一个级别可用。 - 在注解中,一般都会包含一些元素来表示某些值,当分析处理注解时,程序可以利用这些值,而没有元素的注解称为
标记注解
,就像上面的@Test一样。
定义元素
- 在注解中,可以用定义接口的方式一样来定义注解的内容,而这些内容称为元素,如下面代码中的id和description,它们的定义类似于方法的定义,只是跟接口一样,是一个抽象的方法。在这里description元素有一个default值,如果在注解某个方法没有给出description的值,则该注解的处理器会使用默认值。
1 | package com.muchlab.anntation; |
注解的使用
- 注解的元素在使用时表现为名—值对的形式,并将其置于@xxx声明之后的括号内
1 | package com.muchlab.anntation; |
元注解
- JavaSE内置了四种元注解:
注解 | 含义 |
---|---|
@Target | 表示定义好的注解将会被应用在什么地方; CONSTRUCTOR:构造器声明 FIELD:域声明(包括enum实例) METHOD:方法声明 PACKAGE:包声明 PARAMETER:参数声明 TYPE:类、接口、注解或enum声明 |
@Retention | 示该注解在哪一个级别可用; SOURCE:注解将被编译器丢弃 CLASS:注解在class文件中可用,但会被JVM丢弃 RUNTIME:VM在运行期会保留注解,因此可以通过反射机制来读取注解的信息,一般情况下都会使用这个值 |
@Documented | 将此注解包含在Javadoc中 |
@Inherited | 允许子类继承父类中的注解 |
注解处理器
- 在大多数时候,我们都会定义自己的注解,然后编写自己的处理器来出了它们,如果没有用来读取注解的工具,则注解将没有多大用处。所以使用注解的过程中,很重要的一部分是创建与使用
注解处理器
。 - 下面是一个注解处理器,它将读取PassUntils类,查找
@UseCase
标记,并通过注解的元素进行一些操作。下面的程序使用了两个反射方法:getDeclaredMethods
和getAnnotation
,它们都属于AnnotatedElement接口(Class、Field、Method都实现了该接口),getAnnotation需要提供注解的Class对象,它将返回方法的注解对象。
1 | package com.muchlab.anntation; |
注解元素
- 注解中允许的元素类型如下:
- 所有的基本类型,不包括其包装类
- String
- Class
- enum
- Annotation
- 以上类型的数组
- 默认值的限制:
- 元素不能有不确定的值,即元素要么具有默认值,要么在使用注解时提供元素的值
- 不能以null作为默认值
参考资料:Java编程思想