本文最后更新于 1117 天前,其中的信息可能已经有所发展或是发生改变。
注解的概念
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
注解可以用于创建文档,跟踪代码中的依赖性,甚至执行基本的编译时检查,而且还可以作为在spring框架中进行注解试注入 Bean 属性,用来减少写配置文件。注解是以@+注解名在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解,单值注解、完整注解三类。你可以通过反射机制编程实现对这些元数据的访问。当然,你也可以在编译时选择代码里的注释是否只存在于源代码级,或者它也能在 class 文件中出现。
基本类型
- 标记注解(没有变量,只有名称提示),例如:@annotation
- 单一注解(一个变量),例如:@annotation(“data”)
- 完整注解(多个变量),例如:@annotation(value1=”data1″,value2=”data2″)
内置类型
- @Override:只能用于方法,声明重写的方法。
- @Deprecated:只能用于方法,声明不再使用的方法。
- @SuperssWarnings(value={“unchecked”}):可用于注释某段代码,关闭特定的警告信息。
元注解
元注解是用来描述自定义注解(自定义注解必须通过 @interface 关键字来定义)的注解。
- @Target 描述该注解的使用范围,可选的 ElementType 参数包括:
- CONSTRUCTOR:说明此注解只能用于构造器
- FIELD:说明只能用于域
- LOCAL_VARIABLE:局部变量声明
- METHOD:方法声明
- PACKAGE:包声明
- PARAMETER:参数声明
- TYPE:类、接口(包括注解类型)或者是enum声明
- @Retention表示需要在什么级别保存该注释信息,可选的 RetentionPolicy 参数包括:
- SOURCE:注释将被编译器丢掉
- CLASS:注释在class文件中可用,但会被VM丢弃
- RUNTIME:将在运行时也保障注释,因此可以通过反射机制读取注释的信息。
- @Documented:将注释包含在JavaDoc中
- @Inheried:允许子类继承父类中的注释
自定义注解
声明自定义注解:
//此注解(@Annotation)只能用于方法名之前,并且在运行时保持注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}
使用自定义注解:
public class Test{
@MyAnnotation(value="test")
public void method(){
}
}
提取注解
注解可以通过反射提取
- 首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解。
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass){}
- 然后通过 getAnnotation() 方法来获取 Annotation 对象,
public <A extends Annotation> A getAnnotation(Class<A> annotationClass){}
又或者是 getAnnotations() 方法。
public Annotation[] getAnnotations(){}
前一种方法返回标记此元素上指定类型的注解,后一种方法返回标记此元素上的所有注解。
提取注解案例
public class AnnotationTest {
Integer index;
@MyAnnotation(value = "AnnotationTest.setIndex:OK")
public void setIndex(Integer index){
this.index = index;
this.toDesc("setIndex",Integer.class);
}
@MyAnnotation(value = "AnnotationTest.getIndex:OK")
public Integer getIndex(){
this.toDesc("getIndex");
return this.index;
}
private void toDesc(String method,Class<?>... clazz){
Method nowMethod = null;
try {
nowMethod = AnnotationTest.class.getDeclaredMethod(method,clazz);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
if(nowMethod != null){
Annotation myAnnotation = nowMethod.getAnnotation(MyAnnotation.class);
if(myAnnotation instanceof MyAnnotation){
MyAnnotation myA = (MyAnnotation) myAnnotation;
String value = myA.value();
System.out.println(value);
}
}
}
}
