一般程序是通过main方法开始执行
但servlet是通过反射来执行的
反射是获取信息的一种能力
方法/变量/构造器/继承和实现的接口------->统称类信息
通过反射获取类信息
1.使用反射就必须生成类对象
java文件执行过程:
<1>创建一个xxx.java文件--------通过java命令------->转译成xxxx.class文件
<2>加载成类对象
<3>类对象再放入内存执行
此时,变量、方法、构造器都存储在类对象里
生成类对象的三种方式(对应三个阶段)
(1)class.forName("全类名") 对应<1>
PS:全类名=包名+类名;
xxxx.class文件,就是二进制编码文件
(2) 类名.class 对应<2>
(3)对象名.getClass() 对应<3>
2.获取类信息
类信息存储方式一般有两种:
(1)获取相关集合
如:Field[] fields =clas.getDeclaredFields();
(2)直接获取(一般根据名称来获取)
<1>获取变量
常用四种方法:
获取相关集合:
getDeclaredFields和getFields,前者可以无视修饰符获取全部内容,后者只能获取public修饰符修饰的数据
直接获取:
getDeclaredField和getField,差别同上
如:Field[] fields =clas.getDeclaredFields(); 获取集合
Field ageFiled =clas.getDeclaredField("age"); 直接获取
Field nameFiled =clas.getDeclaredField("name"); 直接获取
而使用getFields和getDeclaredField方法时,与之相同,如:Field[] fields1 =clas.getFields();
<2>根据方法名获取方法
程序区分方法的方式来源于方法的签名
方法的签名=方法名称+参数列表
常用四种:
获取相关集合:
getDeclaredMethods和getMethods,二者差别同上
但getMethods在获取非public修饰的信息时可能会获取到同类型的Object方法
直接获取:
getDeclaredField和getField,差别同上
使用方法:getDeclaredMethod("方法名",参数类型.class)
.class便于反射
若方法没有参数,则直接getDeclaredMethods("方法名")
<3>获取构造器
常用四种方法:
获取相关集合:
getDeclaredConstructors和getConstructors,二者差别同上
直接获取:
getDeclaredConstructor和getConstructor,差别同上
使用方法:如getDeclaredConstructor(参数类型.class)
<4>获取接口/父类
获取当前接口/本身实现了多个接口
常用方法:getInterfaces()
注:
1、接口/类都需要用当前的类对象形式来进行接收,如:
Class clas =Class.forName("com.Cat");
Class[] classes =clas.getInterfaces()
1、获取接口中不存在getDeclaredInterfaces()方法,因为接口中不存在非public修饰的情况
2、大多数接口/继承的类都是public类型的,私有的类本身也无法被继承,同理,私有的接口本身也无法存在
对获取的类信息的使用
类里面存在一个默认的不显示的无参构造器
当类中有自定义有参构造器时,对应默认构造器被覆盖
获取该构造器时必须用含Declared的方法
获取private修饰的构造器时用含Declared的方法,但使用时必须暴力反射才能使用
暴力反射可以忽略安全访问修饰符的安全检查
暴力反射:类名.setAccessible(true)
被private修饰的数据的使用,都要提前暴力反射
变量的使用
set用于赋值,set(Object,value)
Object提供内存空间,该处写变量所在的类,value就是变量的值
get用于取值,使用方法:变量名.get(类名)
构造器用来创造对象,赋值时要对构造器强制转换到相应类型
方法的使用
方法的赋值使用invoke执行,使用方法与变量的方法相同