反射
字节码对象:.class文件加载到jvm虚拟机,jvm根据其字节数组创建相对应的class对象,是类的对象。
反射:在程序运行中,通过字节码对象获取获取到类中的成员信息(构造器,方法,字段)。字节码对象是由jvm创建的。
**
获取字节码对象的方式:
方法一:Class.forName(“全类名”)
将字节码文件加载进内存,返回Class对象多用于配置文件,将类名定义在配置文件中。读取文件,加载类
方式二: 类名.class
通过类名的属性class获取,多用于参数的传递
方式三:对象.getclass()
getClass()方法定义在Object类中,多用于对象的获取字节码的方式
1.在反射中获取构造器:
获取所有的构造器
public Constructor<?>[] getConstructors(): 获取所有的public修饰的构造器
public Constructor<?>[] getDeclaredConstructors(): 获取所有的构造器(包括非public)
2. 通过构造器创建对象:
用反射:(找构造器,传递的是参数列表的类型)
public Object newInstance(Object… initargs)
initargs: 调用该构造器传递的实际参数.参数列表一定要匹配(类型,个数,顺序).
我们不能直接访问没有权限(非public)的成员,如果想要使用反射去操作非public的成员.必须设置一个可以访问的标记.
public void setAccessible(boolean flag): 传递一个true,表示可以访问,表示不管权限.
利用反射创建对象:
1.获取字节码对象
2.找到公共构造器
3.调用构造器的newInstance
**
在反射中使用Method类来描述方法这一类事物.(获取方法类)获取多个
获取多个方法类
**
public Method[] getMethods(): 可以获取到所有的公共的方法,包括继承的.
public Method[] getDeclaredMethods():获取到本类中所有的方法,包括非public的,不包括继承的.
获取指定的方法.
public Method getMethod(String name, Class<?>… parameterTypes):
public Method getDeclaredMethod(String name, Class<?>… parameterTypes):
name: 方法名
parameterTypes: 当前方法的参数列表的类型.
定位方法等=某个方法名+参数列表
4.反射调用方法调用方法
public Object invoke(Object obj, Object… args):
obj: 表示调用该方法要作用到那个对象上.
args:调用方法的实际参数
方法的返回值表示,调用该方法是否有返回值,如果有就返回,如果没有,返回null.
注意:
1.如果要访问非public修饰的方法,需要在访问之前设置可访问的标记.
设置method.setAccessible(true);
2.如果方法为static修饰时,invoke第一个参数传null即可。
5.反射操作字段
public Field getField(String name)
public Field getDeclaredField(String name)
public Field[] getFields()
public Field[] getDeclaredFields()
Tomcat中反射的使用
Tomcat具体加载处理细节(1). Tomcat(App)首先读取配置文件web.xml中配置好的Servlet的子类名称(2).Tomcat根据读取到的客户端实现的Servlet子类的类名字符串去寻找对应的字节码文件。如果找到就将其加载到内存。(3).Tomcat通过预先设置好的Java反射处理机制解析字节码文件并创建相应的实例对象。之后调用所需要的方法。【最后】Tomcat一启动,用户自定义的Servlet的子类通过Tomcat内部的反射框架也随之运行。