学习反射之前先来了解一下动态语言:
动态语言: 在程序运行时,可以改变程序的结构或变量的类型。典型的动态语言Python、ruby、JavaScrip
Java 不是动态语言,但具有一定动态性,所以需要反射来实现实现动态性.
好处: Java实现动态性后会让编程变得更加的灵活,功能也更加强大.
反射机制
首先, 程序在运行的过程中加载一些“只知道相关名字”的类; 其次, 类被加载后,JVM 会创建一个对应类的 Class 对象,类的整个结构信息会被放到 Class 对象中; 最后, 这个 Class 对象就像镜子一样,通过这面镜子, 可以得到对应类的全部信息。
反射机制的常见作用:
1) 动态的加载类、动态的获取类的信息(属性,方法,构造器)
2) 动态构造对象
3) 动态调用类和对象的任意方法、构造器
4) 动态调用和处理属性
5) 获取泛型信息
6) 处理注解
获取 Class 对象的方式:
1) 通过字节码文件
2) 对象的 getClass()方法
3) Class 类的静态方法 forName(….)
程序图
运行结果:
反射机制动态操作方法_属性_构造器
使用反射机制获取类的名称和属性的方法:
获取类的名字
1 String getName() 获得包名+类名
2 String getSimpleName() 获得类的名字
获得类的属性
1 Field getField(String fieldName) 得到公共的属性对象
2 Field getDeclareField(String fieldName) 得到指定名称的属性对象
3 Field []c.getDeclaredFields() 得到所有的属性对象
使用反射机制获取方法及构造方法的方法有:
获得类的方法 ------<类当中可以没有带参构造的方法,但一定要有无参构造方法>
1 Method[] getDeclaredMethods() 得到公共的方法 对象
2 Method[] c.getMethods() 得到父类及本类中的公共的方法对象
3 Method getDeclaredMethod(StringmethodName, Class …type)得到指定名称的本类中公共的方法
4 Method getMethod(String methodName,Class type)得到本类或父类中的公共的方法对象
获得构造方法
1 Constructor[] getDeclaredConstructors() 得到公共的构造方法的对象
2 Constructor [] getConstructors() 得到公共的构造方法对象
3 Constructor getDeclaredConstructor(Class...type)得到指定参数的公共的构造方法对象
程序图:
测试图:
提高反射效率
如何提高反射效率:
通过 setAccessible 提高性能
a) setAccessible 启用和禁用访问安全检查的开关&#xff0c;值为true 则指示反射的对象在使用时应该取消 Java 语言访问检查&#xff0c;值为 false 则指示反射的对象不实施 Java 语言访问检查&#xff0c;并不是为 true 就能访问为 false 就不能访问
b) 禁止安全检查&#xff0c;可以提高反射的运行速度
反射操作泛型
Java 中的泛型仅仅是给编译器 javac 使用的&#xff0c;确保数据的安全性和免去强制类型转换的麻烦&#xff0c;但是一旦编译完成&#xff0c;所有与泛型有关的类型全部擦除
Java新增的数据类型有:------<为了通过反射操作这些类型以迎合实际开发的需要>
1) ParameterizedType&#xff1a; 表 示 一 种 参 数 化 的 类 型 ,比 如Collection,可以获取 String 信息
2) GenericArrayType&#xff1a;泛型数组类型
3) TypeVariable&#xff1a;各种类型变量的公共父接口
4) WildcardType&#xff1a;代表一种通配符类型表达式&#xff0c;比如? extends Number,Super Integer
(Wildcard 是一个单词&#xff0c;就是通配符)
程序图:
运行结果:
注解
注解的作用:
1) 不是程序本身&#xff0c;可以对程序作出解释。&#xff08;这一点跟注释没什么区别&#xff09;
2) 可以被其他程序(比如:编译器等)读取。(注解信息处理流程&#xff0c;是注解和注释的重大区别&#xff0c;如果没有注解信息处理流程&#xff0c;则注解毫无意义)
注解的格式
注解是以”&#64;注释名”在代码中存在&#xff0c;还可以添加一些参数值&#xff0c;例如&#64;SuppressWarnings(value&#61;”unchecked”)
注解在哪里使用
可以附加在 package,class,method,field 等上面&#xff0c;相当于给它们添加了额外的辅助信息&#xff0c;我们可以通过反射机制编程实现对这些元素的访问
常见的内置注解有:
1) &#64;Override :标识方法是重写的方法
2) &#64;Deprecated :标识的方法不建议使用
3) &#64;SuppressWarnings&#xff1a;用来抑制编译时的警告信息
程序图:
自定义注解
自定义注解:
使 用 &#64;interface 定 义 自 定 义 注 解 时 &#xff0c; 自 动 继 承 了java.lang.annotation.Annotation 接口
1) &#64;interface 用来声明一个注解
2) 其中的每一个方法实际上是声明了一个配置参数
a) 方法的名称就是参数的名称
b) 返回值类型就是参数类型(返回值类型只能是基本类型、Class、String、enum)
c) 可以通过 default 来声明参数的默认值
d) 如果只有一个成员&#xff0c;一般参数名为 value
自定义注解的注意事项有:
注解元素必须要有值。我们定义注解元素时&#xff0c;经常使用空字符串&#xff0c;0 作为默认值。
也经常使用负数(比如-1)表示不存在的含义
元注解:
元注解的作用就是负责注解其他注解。在 Java 中定义了 4个标准的 meta-annotation 类型&#xff0c;它们被用来提供对其它annotation 类型作说明
它们位于java.lang.annotation 包
1) &#64;Target 2) &#64;Retention 3) &#64;Documented 4) &#64;Inherited
&#64;Target
作用&#xff1a;用于描述注解的使用范围(即被描述的注解可以用在什么地方)
举例:&#64;Target(value&#61;ElementType.TYPE)
&#64;Retention
作用&#xff1a;表示需要在什么级别保存该注解信息,用于描述注解的生命周期
反射读取注解信息
ORM (Object Relationship Mapping)&#xff1a;对象关系映射
举例说明注解的使用
1) 类与表结构对应
2) 属性和字段对应
3) 对象和记录对应
使用注解完成类和表结构的映射关系
我们将Java中的Student类使用第三方程序通过读取注解生成数据库中的表,下面是步骤:
1) 编写 Student 类
2) 编写注解
3) 在类中使用注解
4) 通过解析程序将注解读取出来 (通过框架解析
5) 拼接 SQL 语句&#xff0c;使用 JDBC 到数据库中执行创建表
程序图:
运行结果: