标签:
注解是一种元数据形式,提供关于不是程序部分的程序的数据。操作代码上的注解不影响注解的代码。
注解有许多用途,其中:
编译器信息 —— 注解被用于编译器检测错误或抑制警告。
编译时和部署时处理 —— 软件工具能处理注解信息生成代码、XML文件等等。
运行时处理 —— 一些注解可用在运行时检查。
最简单的注解形式如下所示:
在符号字符(@)告诉编译器这是一个注解。在下面的例子中,注解的名称是Override:
@Override
void mySuperMethod() { ... }
注解能包含已命名或未命名的元素,并且这些元素都有值:
@Author(
name = "Benjamin Franklin",
date = "3/27/2003"
)
class MyClass() { ... }
或
@SuppressWarnings(value = "unchecked")
void myMethod() { ... }
如果只有一个名为value的元素,那么名称可用被省略,如下所示:
@SuppressWarnings("unchecked")
void myMethod() { ... }
如果注解没有元素,那么圆括号可用被省略,就像墙面的@Override。
可用在声明上使用多个注解:
@Author(name = "Jane Doe")
@EBook
class MyClass { ... }
可以使定义在Java SE API的java.lang或java.lang.annotation包中的其中一个类型。在前面的例子中,Override和SuppressWarnings是预定义的Java注解。它也可以定义你自己的注解类型。在之前例子中的Author和Ebook注解是自定义注解类型。
注解可用于声明:类、字段、方法和其它程序元素声明。
许多注解替换代码中的注释。
假设一个软件团队传统每个类体开始使用注释提供重要的信息。
public class Generation3List extends Generation2List {
// Author: John Doe
// Date: 3/17/2002
// Current revision: 6
// Last modified: 4/12/2004
// By: Jane Doe
// Reviewers: Alice, Bill, Cindy
// 这里是类代码
}
为了使用注解添加相同的元数据,你必须先定义注解类型。语法如下:
@interface ClassPreamble {
String author();
String date();
int currentRevision() default 1;
String lastModified() default "N/A";
String lastModifiedBy() default "N/A";
// 注意使用数组
String[] reviewers();
}
注解类型的定义看起来类似于一个接口定义,关键字interface前面有一个符号(@)。注解类型是接口的一种形式。
之前注解体中定义包括注解类型元素声明,看起来像是一个方法。注意他们能定义可选默认值。
在注解类型后面定义,你能使用注解的类型,使用字段的值,如下所示:
@ClassPreamble (
author = "John Doe",
date = "3/17/2002",
currentRevision = 6,
lastModified = "4/12/2004",
lastModifiedBy = "Jane Doe",
// 注意数组符号
reviewers = {"Alice", "Bob", "Cindy"})
public class Generation3List extends Generation2List {
// 这里是类代码
}
注意:为了使@ClassPreamble中的信息出现在生成的javadoc文档中,你必须使用@Documented注解定义@ClassPreamble:
import java.lang.annotation.*;
@Documented
@interface ClassPreamble {
// 注解元素定义
}
Java SE API中预定义了一组注解类型。一些注解类型用于Java编译器,一些应用于其它注解。
定义在java.lang中预定义注解类型是@Deprecated、@Override和@SuppressWarnings。
@Deprecated注解表明标记的元素是弃用的并且不应该再被使用。无论何时程序使用了@Deprecated注解的方法都会产生一个警告、类或字段。当一个元素被弃用时,它应该也应该使用Javadoc的@deprecated标签记录,就像下面的例子一样。在Javadoc注释中使用@符号在注解中并不是凑巧:它们是相关的概念。同样,注意Javadoc标签开始与小写字母d而注解开始于大小字母D。
// 以下是Javadoc注释
/**
* @deprecated
* 解释为什么启用
*/
@Deprecated
static void deprecatedMethod() { }
@Override注解通知编译器,元素原本覆盖一个定义在超类中的元素。
//标记方法为覆盖超类方法
@Override
int overriddenMethod() { }
然后,当一个方法被覆盖时,他不是必须使用的。它有助于防止错误。如果一个方法使用@Override标记未能正确覆盖超类的方法,编译器产生一个错误。
@SuppressWarnings告诉编译器抑制特定警告,否则就会产生。在下面的例子中,一个弃用的方法被使用,编译器通常产生一个警告。在这种情况下,注解导致警告被抑制。
// 使用弃用方法并告诉编译器不产生警告
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
// 抑制弃用警告
objectOne.deprecatedMethod();
}
每个编译器警告属于一种类别。Java语言规范列出两种类别:deprecation(反对)和unchecked(未检查)。泛型出现之前编写的遗留代码会有未检测异常。为了抑制多种警告们使用以下语法:
@SuppressWarnings({"unchecked", "deprecation"})
@SafeVarargs注解,当应用于一个方法或构造函数,断言代码不在它的可变参数上执行潜在的不安全操作。当该注解类型被使用,为关于使用可变参数的检测警告被抑制。
应用于其它注解的注解被称为元数据注解。有几个元数据注解类型定义在java.lang.annontation中。
@Retention注解指定如何标记注解存储:
1)RetentionPolicy.SOURCE — 标记注解只保留在源代码级别,被编译器忽略。
2)RetentionPolicy.CLASS — 标记注解在编译器编译时保留,但是被JVM忽略。
3)RetentionPolicy..RUNTIME — 标记注解被JVM保留因此他能用于运行时环境。
@Documented注解表示无论何时指定注解用于这些元素应该使用Javadoc工具注解(默认,注解不包括在Javadoc中。)
@Target注解标记能应用的Java注解元素其它约束。目标注解指定下面元素类型值:
1)ElementType.ANNOTATION_TYPE 能应用于注解类型。
2)ElementType.CONSTUCTOR 能应用于构造函数。
3)ElementType.FIELD 能应用于字段或属性。
4)ElementType.LOCAL_VARIABLE 能应用于局部变量。
5)ElementType.METHOD 能应用方法级别注解。
6)ElementType.PACKAGE 能应用于包声明。
7)ElementType.PARAMETER 能应用于方法的参数。
8)ElementType.TYPE 能应用于任意类的元素。
@Inherited注解表明注解类型能继承超类。(默认为false。)当用户查询注解类型,而类没有该注解类型,类的超类有该注解类型。该注解只应用于类声明。
标签:
原文地址:http://my.oschina.net/u/2000201/blog/485868