java 注解
java 注解的作用
当创建一个描述符性质的类或接口时,其中包含重复性的工作时,可以考虑使用注解来简化该过程。例如:spring中使用了大量注解来简化bean的转载和实例化过程
java注解组成和定义
元注解:
元注解的作用是负责注解其他注解:简单的说就是负责其他注解说明,和给其他注解限制作用,java中定义的元注解有4种:
- @Target
- @Retention
- @Documented
- @Inherited
@Target 元注解:
该注解说明了Annotation所修饰的对象范围:
例如:
- @Target(value = {ElementType.TYPE}) 表示该注解可以应用于描述类,接口,或enum上,
- @Target(value = {ElementType.CONSTRUCTOR}) 表示该注解用于描述构造器
- @Target(value = {ElementType.FIELD}) 表示该注解可以用于描述域
- @Target(value = {ElementType.LOCAL_VARIABLE}) 表示该注解可以用于描述局部变量上
- @Target(value = {ElementType.METHOD}) 表示该注解可以用与方法上
- @Target(value = {ElementType.PARAMETER}) 表示该注解可以应用于描述方法参数上
要修饰多个范围可以用
例如@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
表示@Retention 注解:
该注解说明了被定义的Annotation保留的时间长短,也就是被定义的注解是否仅出现在源码中不编译,编译成class文件中,不会运行,和该注解可以被虚拟机运行
例如:
- @Retention(value = RetentionPolicy.RUNTIME) 表示该注解可以在运行是有效
- @Retention(value = RetentionPolicy.CLASS) 表示在class文件中有效,虚拟机运行忽略
- @Retention(value = RetentionPolicy.SOURCE) 在源文件中有效,编译器编译忽略
@Documented 注解:
该元注解用于标记注解是否将包含在JavaDoc中
@Inherited 注解:
该注解是一个标记注解,表示是否允许子类继承该注解
注解定义格式:
格式
public @interface 注解名 {定义体}
@interface 是用来声明一个注解
注解定义体中参数的可支持数据类型为:
- java 基本数据类型
- String 类型
- Class 类型
- enum 类型
- Annotation 类型
注解体中的所有参数都是一个方法,并且可以设置默认值,而且非基本类型的注解元素的值必须不为空
例如:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.CLASS) public @interface Test { String value() default "测试"; }
声明一个Test的注解,它的目标为只能作用在类域上,它的生命周期为class,表示不会被虚拟机加载,该注解的元素为一个String 类型的value值,默认为‘测试’
注解的解析和使用:
解析:
java 可以通过反射机制可以获取注解和解析注解,只有当注解的@Retention 被标记为RUNTIME时,虚拟机才会读取class文件中的注解,才可以被解析和获取。
在java 反射机制中,AnnotatedElement 接口是Class,Method,Constructor 的父接口,可以通过该接口的方法获取指定注解和该注解上的值,具体方法如:
- getAnaotation(注解名.class) 获取程序元素是否存在该注解,如果不存在返回null
- Annotation[] getAnnotations() 返回该程序元素上的所有的注解
- boolean isAnnotationPresent(注解名.class) 判断该元素上是否存在指定的注解
- Annotation[] getDeclaredAnnotations() 返回存在于此元素上的所有注释
使用:
实例:
定义一个注解 注意注解使用周期:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Test { String value() default "测试"; }
使用该注解:
public class TestAnnotation { @Test(value = "hello word") public String value; }
解析该注解:
public class AnnotationUtils { public void parse(Class clazz){ Field[] fields=clazz.getDeclaredFields(); for (Field field :fields){ if (field.isAnnotationPresent(Test.class)){ Test test=field.getAnnotation(Test.class); System.out.println(test.value()); } } } public static void main(String [] args){ AnnotationUtils utils=new AnnotationUtils(); utils.parse(TestAnnotation.class); } }