最近几天在学习注解相关的知识点:
一、定义
注解也叫作元数据,就是用来描述数据的数据。它其实就是程序代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取并执行相应的处理。注解主要是告诉编译器要做什么事情,在程序中可对任何程序元素进行注解。其可以声明在包、类。成员变量、成员方法、局部变量、方法参数等的前面,用来对这些程序元素进行说明、注释。
二、分类
根据注解的作用可以分为基本注解、元注解(元数据注解)与自定义注解三种。
基本注解:在JDK8的java.lang包中,java提供了5种基本注解,可以直接在程序代码中将其当做修饰符来使用,用于所支持的程序元素,其分别是@Deprecated,@Override,@SuppressWarnings @SafeVargs @Functionallnterface
元注解:就是对注解进行标注的注解。java中定义了6种元注解类型:@Target @Retention @Document @Inherited @Repeatable和类型注解。
@Target用来限制注解的使用范围,即指定该注解可用于哪些程序元素
@Retention用于说明注解的保存范围,保存范围使用枚举类型java.lang.annotation.RetentionPolicy来指定其保留策略值。
@Document用于指定被修饰的注解可被javadoc.exe工具提取成文档。
@Inherited用于描述一个父类的注解可以被子类继承。
@Repeatable用于开发重复注解。
三、自定义注解,其过程主要包括三个步骤:
1、定义注解,使用@interface进行声明,其实就是继承了java.lang.annotation.Annotation接口.
注解的成员由未实现的方法组成,其中的成员变量以无参数方法的形式来声明,就变量名后面必须有圆括号()
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; /* * 定义一个testannotation */ @Target(ElementType.FIELD)//使用在成员变量上 @Retention(RetentionPolicy.RUNTIME)//在程序执行时生效 @Documented public @interface TestAnnotation { String description() default ""; }
2、解析注解,原理是利用反射来获取注解以及其对应的值
import java.lang.reflect.Field; /* * 注解解析 */ public class TestAnnotationParse { public static String getDescription(Class<?> clazz,int key){ Field[] fields = clazz.getDeclaredFields(); Field f=null; for(Field field:fields){ //将此对象的accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消Java语言访问检查。 //值为 false 则指示反射的对象应该实施 Java 语言访问检查。 field.setAccessible(true); try { //判断是否存在注解,且注解的值跟入参一致 if(field.isAnnotationPresent(TestAnnotation.class)&& Integer.valueOf(field.get(clazz).toString())==key){ f=field; break; } } catch (NumberFormatException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } if(f!=null) //获取变量上注解的值 return f.getAnnotation(TestAnnotation.class).description(); return null; } public static void main(String[] args) { System.out.println(TestAnnotationParse.getDescription(TestAnnotationObject.class, 200)); System.out.println(TestAnnotationParse.getDescription(TestAnnotationObject.class, TestAnnotationObject.RET_CODE_FAIL)); } }
3、使用注解
/* * 使用自定义的注解 */ public class TestAnnotationObject { @TestAnnotation(description="success") public static int RET_CODE_SUCC=200; @TestAnnotation(description="fail") public static int RET_CODE_FAIL=201; }
在以上步骤的第二步中,需要用到反射获取注解,而且要用获取字段信息的方法来获取被注解的字段,
这时候有个困惑,getDeclaredFields与getFields有什么区别?
区别:
getDeclaredFields:获得某个类的所有声明的字段,包括private 、protected、public,但是不包括父类声明的字段;
getFields:获得某个类的所有的公共字段(public),包括父类;
同样类似的还有
getConstructors()和getDeclaredConstructors()、
getMethods()和getDeclaredMethods(),
这两者分别表示获取某个类的构造方法和成员方法。
以上记录下来,以防忘记。