注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻方便的使用这些数据,用来将任何的信息或者元数据与程序元素(类、方法、成员变量等)进行关联。
Annotation其实是一种接口,通过Java的反射机制相关的API来访问Annotation信息。相关框架或工具中的类根据这些信息来决定如何使用该程序元素或改变它们的行为。
一、java.lang.annotation包
(1)Target.java
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
其中@interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字。
(2)源文件Retention.java
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
在上面的文件都用到了RetentionPolicy,ElementType这两个字段。
(3)RetentionPolicy.java
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
这是一个enum类型,共有三个值,分别是SOURCE, CLASS 和 RUNTIME。
(4)ElementType.java
public enum ElementType {
TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR,
LOCAL_VARIABLE, ANNOTATION_TYPE,PACKAGE
}
@Target里面的ElementType是用来指定Annotation类型可以用在哪一些元素上:
如果一个Annotation类型没有指明@Target使用在哪些元素上,那么它可以使用在任何元素之上。
二、自定义注解的语法
代码实例
(1)定义两个注解,Description和Name。
Description.java
package com.ljq.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
String value();
}
Name.java
package com.ljq.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注意这里的@Target与@Description里的不同,参数成员也不同
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Name {
String originate();
String community();
}
(2)在一个类中使用注解
JavaEyer.java
package com.ljq.test;
@Description("javaeye,做最棒的软件开发交流社区")
public class JavaEyer {
@Name(originate = "创始人:robbin", community = "javaEye")
public String getName() {
return null;
}
@Name(originate = "创始人:江南白衣", community = "springside")
public String getName2() {
return "借用两位的id一用,写这一个例子,请见谅!";
}
}
(3)提取注解内容
package com.ljq.test;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
public class TestAnnotation {
public static void main(String[] args) throws Exception {
String CLASS_NAME = "com.ljq.test.JavaEyer";
Class test = Class.forName(CLASS_NAME);
Method[] method = test.getMethods();
boolean flag = test.isAnnotationPresent(Description.class);
if (flag) {
Description des = (Description) test
.getAnnotation(Description.class);
System.out.println("描述:" + des.value());
System.out.println("-----------------");
}
// 把JavaEyer这一类有利用到@Name的全部方法保存到Set中去
Set set = new HashSet();
for (int i = 0; i < method.length; i++) {
boolean otherFlag = method[i].isAnnotationPresent(Name.class);
if (otherFlag)
set.add(method[i]);
}
for (Method m : set) {
Name name = m.getAnnotation(Name.class);
System.out.println(name.originate());
System.out.println("创建的社区:" + name.community());
}
}
}
输出
描述:javaeye,做最棒的软件开发交流社区
-----------------
创始人:robbin
创建的社区:javaEye
创始人:江南白衣
创建的社区:springside
Class对象和Method对象关于注解的方法:
(1) A getAnnotation(Class annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
(2) Annotation[] getAnnotations()
返回此元素上存在的所有注释。
(3)boolean isAnnotationPresent(Class