概念:
☆ 注解(@interface)是一种元数据,是一种代码级别的说明
☆ 是JDK5.0及以后版本引入的一个特性
☆ 与包package、类class、接口interface、枚举enum是在同一层次
☆ 可以声明在包、类、子段、方法、局部变量、方法参数之前。
注解的作用:
1. 编写文档:通过代码里标识的元数据生成文档
2. 代码分析:通过代码里标识的元数据对代码进行分析
3. 编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查
4. 跟踪代码依赖性,实现替代配置文件。比较常见的是spring2.4开始的基于注解配置。作用就是减少配置。现在的
框架基本都使用了这种配置来减少配置文件的数量。
注解的语法和定义形式:
a. 用@interface关键字定义
b.注解包含成员,成员是由无参数的方法的形式被声明的,器其方法名和返回值定义了该成员的名字和类型
c.成员赋值通过@Annotation(name="value")的方式
d.注解需要标明注解的生命周期、修饰目标信息,这些都是通过元注解实现
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value={ElementType.ANNOTATION_TYPE})
public @interface Target{
ElementType[] value();
}
如果成员名是value,则可以简写,如果成员类型是数组,但是只赋值一个元素,也可以简写,以上简写为:
@Target(ElementType.ANNOTATION_TYPE)
注解的分类:
注解分为两类:
一类是元注解(修饰注解的注解)
另一个是普通注解
如何判断一个注解是不是元注解呢?看它的元注解就行(无论是元注解还是普通注解,都有元注解),
@Target(ElementType.ANNOTATION_TYPE)这个就是元注解,作用在元注解之上
注解的声明周期:
注解需要标明生命周期,这些信息是通过元注解来实现的,而这个元注解是:
public @interface Retention{
RetentionPolicy value();
}
Retention注解的值是enum类型的RetentionPolicy。包括如下几种情况:
● SOURCE:注解只是保存在源文件中,当Java文件被编译成class文件的时候,注解被遗弃。
● CLASS: 注解被保留到class文件中,当被加载的时候,注解被遗弃。
● RUNTIME:注解不仅保存在class文件中个,jvm加载class文件之后,仍然存在,保留到Class对象中,可以通过反射来获取
注解修饰的目标:
就是这个注解可以写在哪里。
首先是这个元注解的实现:
public @interface Target{
ElementType[] value();
}
这个注解的值是enum类型ElementType。包括以下几种情况:
-
TYPE:可以在类型上进行注解,比如类、接口、enum上使用的注解
-
FIELD:在声明的常量上
-
METHOD:在方法上使用
-
PARAMETER:指的是在参数上使用的注解
-
LOCAL_VARIABLE:局部变量上使用
-
在注解上使用元注解ANNOTATION_TYPE:
-
PACKAGE:在包上使用注解
注解的底层实现:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.lang.model.element.Element;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Cache {
String value() default "cache";
}
1.public interface Cache extends java.lang.annotation.Annotation,注解是继承自
Annotation,仍然是interface
2.public abstract java.lang.String value(),说明value方法是abstract类型
三个基本的注解:
1. @override 标记这是重写了父类的方法,只存在于源码中的注解
2. @deprecated 标记这个方法已经是废除的方法
3. @SupportWarning 压住一切警告信息
注解案例:
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassInfo {
String name() default "";
}
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo {
String name() default "";
}
package annotation;
@ClassInfo(name="学霸班级")
public class ClassOne {
@MethodInfo(name="学习非常刻苦")
public void study(){
}
}
package annotation;
import java.lang.reflect.Method;
import org.junit.Test;
public class AnnotationParse {
public static void parse(){
Class clazz = ClassOne.class;
if(clazz.isAnnotationPresent(ClassInfo.class)){
ClassInfo classInfo = (ClassInfo) clazz.getAnnotation(ClassInfo.class);
System.out.println(classInfo.name());
}
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if(method.isAnnotationPresent(MethodInfo.class)){
MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);
System.out.println(methodInfo.name());
}
}
}
@Test
public void testAnnotationParse(){
parse();
}
}