1.13.1 Annotations and Annotation Types 注解和注解类型
Annotations are notes in Java programs to instruct the Java compiler to do something. Java provides three standard annotations and four standard meta-annotations.
注解是Java程序中的注释, 用于指示Java编译器去做某事. Java提供
3种标准 注解 和4种标准 元注解.
An annotation type is a special interface type.
An annotation is an instance of an annotation type.
An annotation type has a name and members.
注解类型时一种特殊的接口类型.
注解是注解类型的实例.
注解类型有名称和(方法)成员.
The information contained in an annotation takes the form of key/value pairs.
There can be zero or multiple pairs and each key has a specific type.
It can be a String, int, or other Java types.
包含在注解里的信息以 键/值 对的形式呈现.
可以有零个或多个对. 每个键拥有具体的类型.
键可以是String, int 或其他Java类型.
Annotation types with no key/value pairs are called marker annotation types.
Those with one key/value pair are referred to single-value annotation types.
There are three annotation types in Java 5: Deprecated, Override, and Suppress Warnings.
不带 key/value 对的注解类型被称为 标记(marker)注解类型.
带有一个 key/value 对的被称为 单值注解类型.
在Java 5 中有3种注解类型: 已过时, 覆盖 和 压制警告.
There are four other annotation types that are part of the java.lang.annotation package: Documented, Inherited, Retention, and Target.
These four annotation types are used to annotate annotations,
另有4种 元注解类型作为 java.lang.annotation包的一部分:
文档, 继承, 保留 和 目标.
1.13.2 The Annotation Interface : Annotation接口
An annotation type is a Java interface.
All annotation types are subinterfaces of the java.lang.annotation.Annotation interface.
It has one method, annotation Type, that returns an java.lang.Class object.
一个注解类型是一个Java接口.
所有的注解类型都是 java.lang.annotation.Annotation 接口的子接口.
它有方法annotationType(), 返回 java.lang.Class 对象.
java.lang.Class<? extends Annotation> annotationType()
In addition, any implementation of Annotation will override the equals, hashCode, and
toString methods from the java.lang.Object class.
再者, Annotation的任何实现将会覆盖 java.lang.Object 类的 equals, hashCode 和 toString 方法.
1.13.3 Using Default Values 使用默认值
Annotation default values is used if no value is specified.
A default value is specified by adding a default clause.
Default value must be of a type compatible with type.
如果不指定值, 则注解的默认值被使用.
通过增加default子句指定默认值.
默认值必须类型兼容.
下面重写 @MyAnnotation 以包含默认值.
@Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String stringValue() default "defaultString"; int intValue() default 101; }
以下4种使用方式对于 @MyAnnotation 都是合法的.
@MyAnnotation() // both str and val default @MyAnnotation(stringValue = "some string") // val defaults @MyAnnotation(intValue = 100) // str defaults @MyAnnotation(stringValue = "Testing", intValue = 100) // no defaults
import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; // A simple annotation type. @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String stringValue() default "defaultString"; int intValue() default 101; } @MyAnnotation(stringValue = "for class", intValue = 100) public class MainClass { // Annotate a method. @MyAnnotation(intValue = 100) public static void myMethod() { } public static void main(String[] arg) { try { MainClass ob = new MainClass(); Method m = ob.getClass( ).getMethod("myMethod"); Annotation[] annos = m.getAnnotations(); System.out.println("All annotations for myMeth:"); for(Annotation a : annos) System.out.println(a); } catch (Exception exc) { } } } /* All annotations for myMeth: @MyAnnotation(stringValue=defaultString, intValue=100) */
1.13.4 Marker Annotations 标记型注解
Marker Annotations are used to mark a declaration.
A marker annotation is a special kind of annotation.
A marker annotation contains no members.
Using isAnnotationPresent( ) to determine if the marker is present.
标记型注解被用于标记一个声明.
标记型注解是注解中特殊的一种.
标记型注解不包含任何成员.
使用 isAnnotationPresent() 去确定 marker是否存在.
import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { } @MyAnnotation public class MainClass { // Annotate a method. @MyAnnotation() public static void myMethod() { } public static void main(String[] arg) { try { MainClass ob = new MainClass(); Method m = ob.getClass( ).getMethod("myMethod"); Annotation[] annos = m.getAnnotations(); System.out.println("All annotations for myMeth:"); for(Annotation a : annos) System.out.println(a); } catch (Exception exc) { } } } /* All annotations for myMeth: @MyAnnotation() */
说明: 使用标记型注解时, 后面的括号 () 可有可无.
1.13.5 Single-Member Annotations 单值型注解
Single-Member Annotations contains only one member.
Single-Member Annotations allow a shorthand form of specifying the value.
The name of the member must be value.
单值型注解只包含一个成员.
单值型注解允许以简短形式执行值.
成员的名必须是 value
import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { int value(); } @MyAnnotation(102) public class MainClass { // Annotate a method. @MyAnnotation(101) public static void myMethod() { } public static void main(String[] arg) { try { MainClass ob = new MainClass(); Method m = ob.getClass( ).getMethod("myMethod"); Annotation[] annos = m.getAnnotations(); System.out.println("All annotations for myMeth:"); for(Annotation a : annos) System.out.println(a); } catch (Exception exc) { } } } /* All annotations for myMeth: @MyAnnotation(value=101) */
1.13.6 Creates and uses a single-member annotation 创建和使用单值型注解
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MySingle { int value(); // this variable name must be value } class Single { @MySingle(100) public static void myMeth() { Single ob = new Single(); try { Method m = ob.getClass().getMethod("myMeth"); MySingle anno = m.getAnnotation(MySingle.class); System.out.println(anno.value()); // displays 100 } catch (NoSuchMethodException exc) { System.out.println("Method Not Found."); } } public static void main(String args[]) { myMeth(); } } //100
1.13.7 单值语法
Using the single-value syntax when applying an annotation that has other members, if other members all have default values.
使用具有其他成员的单值型注解时(每个其他成员都有默认值), 可以使用单值语法,
例如:
@interface SomeAnno { int value(); int xyz() default 0; } @SomeAnno(88)
import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { int value(); int defaultValue() default 100; } @MyAnnotation(102) public class MainClass { // Annotate a method. @MyAnnotation(101) public static void myMethod() { } public static void main(String[] arg) { try { MainClass ob = new MainClass(); Method m = ob.getClass( ).getMethod("myMethod"); Annotation[] annos = m.getAnnotations(); System.out.println("All annotations for myMeth:"); for(Annotation a : annos) System.out.println(a); } catch (Exception exc) { } } } /* All annotations for myMeth: @MyAnnotation(defaultValue=100, value=101) */
1.13.8 一些限制 some restrictions
No annotation can inherit another.
All methods declared by an annotation must be without parameters.
Annotations cannot be generic.
They cannot specify a throws clause.
They must return one of the following:
一个注解不可以继承另一个注解.
注解中声明的所有方法, 必须是没有参数的.
注解不可以是泛型的.
注解不可以指定throws子句.
注解必须返回如下之一:
A simple type, such as int or double,
An object of type String or Class
An enum type
Another annotation type
An array of one of the preceding types
一个简答类型, 比如 int 或 double,
类型String或Class的一个对象,
一个 枚举(enum) 类型,
另一个 注解类型
以上某类型的数组.
1.13.9 例子: 一个标记型注解
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @interface MyMarker { } class Marker { @MyMarker public static void myMeth() { Marker ob = new Marker(); try { Method m = ob.getClass().getMethod("myMeth"); if (m.isAnnotationPresent(MyMarker.class)) System.out.println("MyMarker is present."); } catch (NoSuchMethodException exc) { System.out.println("Method Not Found."); } } public static void main(String args[]) { myMeth(); } } //MyMarker is present.