java ----> 注解/反射
2021-05-16 21:27
标签:div 反射技术 博客 例子 动态 test 分配 retention 位置 注解 一个例子,摘自Junit-4.12.jar源码。 关注两个元注解和两个类,它们位于java.lang.annotation包中。 @Retention(RetentionPolicy.RUNTIME) 1、@Retention和RetentionPolicy @Retention 表示要保留带注释类型的注释的时间长度。可以理解为注解的生命周期。 如果注释类型声明中不存在Retention注释,则保留策略默认为RetentionPolicy.CLASS。 RetensionPolicy 注释保留策略。RetensionPolicy是一个枚举类型的类。 此枚举类型的常量描述了用于保留注释的各种策略。 它们与Retention元注释类型结合使用,以指定保留注释的时间。有三个枚举类型的常量,分别是SOURCE,CLASS,RUNTIME。它们分别对应java源文件阶段,class文件阶段,内存中的字节码阶段。(参考博客:https://www.cnblogs.com/xdp-gacl/p/3622275.html) SOURCE:表示编译器会丢弃注解。 CLASS:这是默认的保留策略。表示编译器会在类文件中记录注解,但是在运行时VM不会保留注解。 RUNTIME:表示编译器会在类文件中记录注解,并且在运行时VM会保留注解。可以通过反射技术读取注解。 2、@Target和ElementType @Target 表示注释类型可用的上下文环境。 ElementType 元素类型。ElementType是一个枚举类型的类。描述了注解在java编程中可能出现的语法位置。 它们与Target元注释类型结合使用,以指定给定类型的注解的合法位置。有10个枚举类型的常量,分别是TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE、TYPE_PARAMETER、TYPE_USE TYPE:类,接口(包括注解),枚举声明 FIELD:字段(包括枚举的常量)声明 METHOD:方法声明 PARAMETER:格式化参数声明 CONSTRUCTOR:构造器声明 LOCAL_VARIABLE:局部变量声明 ANNOTATION_TYPE:注解类型声明 PACKAGE:包声明 定义一个注解 注解的本质 注解是一个特殊的类,更像是一个接口。 注解和反射的关系 说明:ClassName表示某个类的名称;AnnotationName表示某个注解的名称。 通过反射技术可以获取注解的信息。 获取注解:Method#getAnnotation(AnnotationName.class) 或者:ClassName.class.getAnnotation(AnnotationName.class) 检查注解是否存在:ClassName.class.isAnnotationPresent(AnnotationName.class) 反射 1、反射:在运行状态中,动态获取对象的信息或者动态调用对象的方法的技术。 2、RTTI(run-time type identification),运行时类型识别,在运行时识别一个对象的类型和类的信息。两种方式:编译期已经知道所有类型;通过反射机制在运行时获取类型的信息。 3、Class:java中获取运行时类型信息的类。 Class对象的作用:为Java虚拟机(JVM)创建实例对象或者提供静态变量的引用值的媒介。Class对象由类加载器子系统加载到JVM中。Class对象是被按需加载的。 获取Class对象的方式: 1)、Class.forName("...") 2)、ClassName.class,不会触发类的初始化 3)、obj.getClass() 4、类的加载过程: 加载 -> 链接(验证->准备->解析)->初始化 加载:已加载字节码文件,可通过它创建Class对象 链接: 验证:安全性和完整性 准备:为静态变量分配空间 解析:处理类中的其他所有引用 初始化:对超类初始化和静态变量,静态代码块等初始化。 5、关注一个类和一个类库: java.lang.Class 方法: forName("指定类的全限定名") // 获取Class对象的引用 newInstance() // 实例化默认构造方法 ①构造方法 getConstructor(指定参数类型,一个或者多个) // 获得指定参数类型的public构造方法,只有一个 getConstructors() // 获得所有public构造方法 getDeclaredConstructor(指定参数类型,一个或者多个) // 获得指定参数类型的构造方法(包括private),只有一个 getDeclaredConstructors() // 获得全部的构造方法(包括private),返回数组 ②属性 getField("指定属性名称") // 获得指定名称 的public属性,属性必须存在 getField() // 获得所有public属性,包括父类,属性必须存在 getDeclaredField("指定属性名称") // 获得指定名称的属性(包括private),不包含父类的属性 getDeclaredField() //获得所有声明的属性(包括private),返回数组,不包含父类的属性 ③方法 getMethod("指定方法名称",指定参数类型) // 获得指定方法名称和参数类型的public方法 getMethods() // 获得所有public方法 getDeclaredMethod("指定方法名称") //获得指定方法名称的方法(包括private),不包含父类的方法 getDeclaredMethods() // 获得所有声明的方法(包括private),返回数组,不包含父类的方法 java.lang.reflect类库,类库中常用的几个类:Constructor,Field,Method。 ①Constructor getParameterTypes() // 获得构造方法参数类型,返回Class类型数组 getDeclaringClass() //返回Class对象,可以用过Class.getName()获得类的全限定名 getGenericParameterTypes() // 获得构造方法的形参类型,返回Type类型数组。 newInstance(Object... initargs) // 通过构造方法创建实例 ②Field setAccessible(true) // 设置该private属性可以被访问到,false表示该属性不可被访问到 getType() // 返回该属性声明的类型 getName() // 返回指定field的名字 get(Object obj) // 返回指定field的值 set(Object obj, object value) // 重新设置指定field的值 ③Method setAccessible(true) //设置该private方法可被访问,false表示该方法不可被访问到 invoke(Object obj,Object... args) // 调用指定方法名和参数的方法 getReturnType() // 获得方法的返回类型 getName() // 获得方法名称 参考:《jdk1.8.0_172-src》《jdk1.8.0_172-docs-all》 注解/反射,soscw.com" target="_blank">java ----> 注解/反射 标签:div 反射技术 博客 例子 动态 test 分配 retention 位置 原文地址:https://www.cnblogs.com/mrray1105/p/9664303.html1 @Retention(RetentionPolicy.RUNTIME)
2 @Target({java.lang.annotation.ElementType.METHOD})
3 public @interface Test{
4
5 //......
6 }
@Target(java.lang.annotation.ElementType.METHOD)1 public @interface FirstAnnotation{}