一.Java反向概述
1.什么是反射
在计算机领域,反射指一种能力,能够自描述和自控制,即运行状态中,动态获取类信息及动态调用实例方法的能力。
1.反射的3个动态特性
1.运行时创建实例。
2.运行期间调用方法
3.运行时更改属性
2.Java反射常用的API
1.使用Java反射技术,常用的类如下
1.java.lang.Class<T>类:反射的核心类,反射所有的操作都围绕该类来生成。通过Class类可以获取类的属性、方法等内容信息。
2.java.lang.reflect.Constructor<T>:表示类的构造方法。
3..java.lang.reflect.Field类:表示类的属性,可以获取和设置类中属性的值。
4..java.lang.reflect.Method类:表示类的方法,可以用来获取类中方法的信息或执行方法。
二.反射的应用
1.获取类的信息
一个类或接口被加载后,从系统中都能获得一个代表该 类或接口的Class类型的实例,通过该实例就可以访问到Java虚拟机中的这个类或接口。
1.获取Class实例
1.Java程序中获得Class实例通常有如下3种方式,可根据实例情况灵活选择。
①.调用类或接口实例得到getClass()方法。
getClass()方法是java.lang.Object类中的一个方法,所有类和接口的实例都可以调用该方法,该方法会返回该实例的所属类型对应的Class实例。
方法代码如下:Class clz = obj.getClass(); //obj为某个类型的实例
②.调用类或接口的class属性。
在某些类或接口没有实例或无法创建实例的情况下,可以通过class属性获取所对应的Class实例,这种方式需要在编译期就知道类或接口的名称。
方法代码如下:Class clz = Student.class; //Student为自定义的学生类型
③.使用Class.forName()方法。
若编码时无法确定具体类型,需要程序在运行时根据情况灵活加载,可以使用Class类的forName()方法。该方法是静态方法,需要传入字符串参数,该字符串参数的值是某个类的完全限定类名,即包含包名的完整类名。
4
方法代码如下: Class clz = Class.forName("com.mysql.cj.jdbc.Driver");
2.从Class实例获取信息
1.获取对应类型的基本信息,相关方法如下表所示:
String getName() | 以字符串形式返回该类型的名称 |
String getSimpleName() | 以字符串形式返回该类型的简称(类名) |
Package getPackage() | 获取该类型所在的包 |
Class getSuperclass() | 获取该类型的超类的Class类型 |
Class[] getInterfaces() | 返回该类型实例的全部接口的Class实例 |
int getModifiers() | 返回该类型所实例的所有修饰符,由public、protected、private、final、static、abstract等对应的int常量组成,返回的整数应使用Modifier工具类来解码,才可以判断修饰符的构成。 |
Class[] getDeclaredClasses() | 返回该类型中包含的全部内部类的Class实例 |
Class getDeclaringClass() | 返回该类型所在的外部类的Class实例 |
2.获取对应类型所包含的构造方法,常用方法如下表所示:
Constructor getConstructor(Class... params) | 返回该类型指定参数列表的public 构造方法,构造方法的参数列表与params 所指定的类型列表所匹配 |
Constructor[] getConstructors() | 返回该类型的所有public 构造方法 |
Constructor getDeclaredConstructor(Class... params) | 返回该类型的指定参数列表的构造方法,访问级别不限 |
Constructor[] getDeclaredConstructors() | 返回该类型的指定参数列表的构造方法,访问级别不限 |
Constructor getDeclaredConstructor() | 获取该类型的无参构造函数 |
3.获取对应类型所包含的属性,常用方法如下表所示:
Field getField(String name) | 返回该类型中指定名称的public属性,name参数用于指定属性名称。 |
Field[] getFields() | 返回该类型中所有public属性 |
Field getDeclaredField(String name) | 返回该类型中指定名称的属性,与属性的访问级别无关 |
Field[] getDeclaredFields() | 返回该类型中的全部属性,与属性的访问级别无关 |
4.访问对应类型所包含的方法,常用方法如下表所示:
Method getMethod(String name,Class... params) | 返回该实例中指定的public方法,,name参数用于指定方法名称,params参数指定参数列表 |
Method[] getMethods() | 返回该实例中所有public方法 |
Method getDeclaredMethod(String name,Class... params) | 返回该实例中指定的方法,与方法的访问级别无关 |
Method[] getDeclaredMethods() | 返回该实例中的全部方法,与方法的访问级别无关 |
5.使用Field实例可以对属性进行取值或赋值操作,主要方法如表:
xxx getXxx(Object obj) | xxx表示8种基本数据类型之一,如 int getInt(Object obj).obj 为该属性所在类的实例。假设 instance 表示A类的实例,field表示A类中的属性a,则field.getInt(instance)表示 以int类型返回instance中的属性a的值。若Field实例表示的是一个静态属性,则obj可以设置为null |
Object get(Object obj) | 以Object类型返回obj中相关属性的值 |
void setXxx(Object obj,xx val) | 将obj中相关属性的值设置为val。xxx为8种基本数据类型之一 |
void set(Object obj,Object val) | 将obj中的相关属性的值设置为val |
void setAccessible(boolenan flag) | 对相关属性设置访问权限。设置为true可以禁止Java语音访问检查 |