一、反射机制概述
1、Java反射机制是在运行状态中,对于任意一个类(.class文件),都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制
即 动态获取类中信息,就是Java反射
2、如果想要对指定名称的字节码文件进行加载、获取其中的内容并调用,就使用反射技术
注:在任何情况下,想要获取类的信息,首先要获取到这个类的类类型(Class)
3、反射要有接口和配置文件
补充:在应用程序A对外暴露接口Inter的同时,还要获取日后产生的功能性的类文件B(B implements Inter),所以,又对外提供了一个配置文件xxx.xml。将符合接口Inter的子类名称B写入配置文件,应用程序A读取配置文件(使用流)。之后,应用程序A根据类名B找到对应的.class文件,加载该文件,并获取该文件中的所有内容,对其进行调用
eg:应用程序Tomcat:提供了处理请求和应答方式。但因为具体的处理动作不同,所以,对外提供了Servlet接口,由开发者来实现具体请求和应答处理。Tomcat除了提供Servlet接口外,每创建一个web应用程序,都有一个配置文件web.xml(路径:Tomcat\webapps\项目名称\WEB-INF\web.xml)。如果有自己的处理请求和应答方式MyServlet(MyServlet implements Servlet),想让Tomcat服务器运行你的处理请求和应答方式MyServlet,就需要将你的MyServlet的相关内容配置到Tomcat提供的配置文件web.xml中(加标签)。这样,Tomcat服务器一启动,你的MyServlet类就跑起来了。Tomcat服务器在动态地获取MyServlet类中的所有信息,并调用MyServlet类中的信息 -- 必须由反射技术来完成
补充:
做Tomcat服务器端最简单的步骤:
(1)Xxx类必须得实现一个接口
(2)将Xxx类名配置到web.xml中(Tomcat\webapps\项目名称\WEB-INF\web.xml)
Tomcat一启动,会将配置文件web.xml下的所有类都加载进来
<servlet>
<servlet-name>xxx</servlet-name>
<servlet-class>zzz</servlet-class>
</servlet>
4、反射技术提高了程序的扩展性,方便用户操作
二、java.lang.Class
1、java.lang.Class<T>:参数T:由此Class对象建模的类的类型。eg:String.class的类型是Class<String>。如果将被建模的类未知,则使用Class<?>
2、用于描述字节码文件的类 class Class{ ... },提供获取字节码文件中的内容(名称、字段、构造函数、一般函数)。该类可以获取字节码文件中的所有内容。反射就是依靠该类来完成的
3、想要对一个类文件进行解剖,只要获取到该类的字节码文件对象即可
4、Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass()方法自动构造的
5、方法
(1)static Class<?> forName(String className) throws ClassNotFoundException:返回与带有给定字符串名的类或接口相关联的Class对象
//以下代码片段返回命名为 java.lang.Thread 的类的运行时Class描述符
//调用forName("Xxx")将导致命名为Xxx的类被初始化
Class t = Class.forName("java.lang.Thread");
(2)ClassLoader getClassLoader():返回该类的类加载器
(3)T newInstance() throws InstantiationException, IllegalAccessException:创建此Class对象所表示的类的一个新实例。如同用一个带有一个空参数列表的new表达式实例化该类。如果该类尚未初始化,则初始化这个类
String className = "xxx";
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
(4)Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException:返回一个Constructor对象,它反映此Class对象所表示的类的指定公共构造方法。parameterTypes参数是Class对象的一个数组,这些Class对象按声明顺序标识构造方法的形参类型。如果此Class对象表示非静态上下文中声明的内部类,则形参类型作为第一个参数包括显示封闭的实例
注:要反映的构造方法是此Class对象所表示的类的公共构造方法,其形参类型与parameterTypes所指定的参数类型相匹配
String className = "xxx";
Class clazz = Class.forName(className);
//任何数据类型都可以被 Class 所描述
//获取指定的构造函数对象
Constructor constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("zhangsan", 20);
(5)Constructor<?>[] getConstructors() throws SecurityException:返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示的类的所有公