您的位置:首页 > 编程语言 > Java开发

JDK 1.5 新特性学习笔记(4)

2011-06-27 08:43 393 查看
5. Annotation(注解)

Annotation是一种元数据(metadata),即“Information about information”,在源代码中标记。

注解使用类Javadoc的语法,@ANNOTATION_NAME(参数),参数为KEY=VALUE的形式。

5.1 内置注解类型
内置的注解类型位于java.lang包中,不需导入,开箱即用。

5.1.1. Override
标明方法覆写了基类的方法。此注解为一种标识注解,无参数。

JDK源码如下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

5.1.2. Deprecated
表明不推荐使用。此注解为一种标识注解,无参数。

JDK源码如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated {
}

5.1.3. SuppressWarnings
关闭类、方法、属性等的指定编译器警告。此注解接收一个String[]类型的参数。

JDK源码如下:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}


SuppressWarnings注解用法示例:
@SuppressWarnings(value={"unchecked"})
public void nonGenericsMethod( ) {
List list = new ArrayList( );
list.add("foo");
}

5.2 注解的注解
注解的注解即描述元数据的元数据,如上述注解的JDK源代码中的注解。

5.2.1 Target
标明注解可以作用的目标范围。

JDK源码如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}

其中ElementType的取值为:

TYPE:类、接口(包含注解)、枚举类型

FIELD:属性(包含枚举类型的值)

METHOD:方法

PARAMETER:方法参数

CONSTRUCTOR:构造方法

LOCAL_VARIABLE:局部变量

ANNOTATION_TYPE:注解类型

PACKAGE:包

JDK源代码:
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,

/** Field declaration (includes enum constants) */
FIELD,

/** Method declaration */
METHOD,

/** Parameter declaration */
PARAMETER,

/** Constructor declaration */
CONSTRUCTOR,

/** Local variable declaration */
LOCAL_VARIABLE,

/** Annotation type declaration */
ANNOTATION_TYPE,

/** Package declaration */
PACKAGE
}

5.2.2 Retention
标明注解可以保持的范围。
JDK源码如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}

其中RetentionPolicy的取值为:

SOURCE:源代码,编译器自动忽略

CLASS:类,默认设置,编译器将其记录在class文件中,但虚拟机运行时不保留

RUNTIME:运行时,编译器将其记录在class文件中,虚拟机运行时将其保留,可以通过反射获取

JDK源码:

public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,

/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time.  This is the default
* behavior.
*/
CLASS,

/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}


5.2.3 Documented
标明Javadoc文档中需包含此注解内容。

JDK源码如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

注:Documented注解的使用要求注解的RetentionPolicy的设置为RUNTIME
5.2.4 Inherited
标明作用于class上的注解是被自动继承的注解。
JDK源码如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}


注意:

1. Inherited注解的使用要求注解的RetentionPolicy的设置为RUNTIME

2. 接口上的注解即使是标明了@Inherited的注解,也不会被继承

3. 基类方法上的注解如果标明了@Inherited则会被继承,但在被子类覆写后也会丢失注解信息
5.3 自定义注解类型
注解类型本质上是一种Java的接口,但使用@interface关键字进行声明。

示例:

public @interface Todo {
public enum Severity {CRITICAL, IMPORTANT, TRIVIAL, DOCUMENTATION};
String description();
String assignedTo();
}


使用示例:

@Todo(
severity=Todo.Severity.CRITICAL,
description="Figure out the amount of order",
assignedTo="Tom"
)
public void calculate() {
// Need to finish this method later
}

5.5 新增的反射API

在java.lang.reflect包中新增了AnnotatedElement接口,JDK源码如下:

public interface AnnotatedElement {
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
Annotation[] getAnnotations();
Annotation[] getDeclaredAnnotations();
}


isAnnotationPresent:判断是否标注了指定注解

getAnnotation:获取指定注解,没有则返回null

getAnnotations:获取所有注解,包括继承自基类的,没有则返回长度为0的数组

getDeclaredAnnotations:获取自身显式标明的所有注解,没有则返回长度为0的数组

reflect包中的相关类如Class等都实现了此接口。

注:反射要求注解的RetentionPolicy的设置为RUNTIME
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: