Java的反射机制以及使用场景
- 什么是反射
- Class对象
- 如何使用
- 获取 Class 类对象
- 反射创造对象
- 反射获取类的构造器
- 反射获取类的成员变量
- 反射获取类的方法
- 反射的应用场景
- JDBC 的数据库的连接
- Spring 框架的使用
什么是反射
Oracle 官方对反射的解释
Reflection is commonly used by programs which require the ability to examine or
modify the runtime behavior of applications running in the Java virtual machine.
This is a relatively advanced feature and should be used only by developers who
have a strong grasp of the fundamentals of the language. With that caveat in
mind, reflection is a powerful technique and can enable applications to perform
operations which would otherwise be impossible.
Java 的反射机制是指:
- 在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;
- 并且对于任意一个对象,都能够调用它的任意一个方法;
- 这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。
白话解释
万物有阴必有阳,有正必有反。既然有反射,就必有“正射”。
那么正射是什么呢?
- 正射
我们在编写代码时,当需要使用到某一个类的时候,都会先了解这个类是做什么的。然后实例化这个类,接着用实例化好的对象进行操作,这就是正射。
Student student = new Student();
student.doHomework("数学");
- 反射
反射就是,一开始并不知道我们要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了。
Class clazz = Class.forName("reflection.Student");Method method = clazz.getMethod("doHomework", String.class);Constructor constructor = clazz.getConstructor();Object object = constructor.newInstance();method.invoke(object, "语文");
正射与反射对比
以上两段代码,执行效果是一样的,如图:
但是,其实现的过程还是有很大的差别的:
第一段代码在未运行前就已经知道了要运行的类是Student;
第二段代码则是到整个程序运行的时候,从字符串reflection.Student,才知道要操作的类是Student。
结论
反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
Class对象
要理解Class对象,我们先来了解一下RTTI吧。
RTTI(Run-Time Type Identification)运行时类型识别,其作用是在运行时识别一个对象的类型和类的信息。
Java是如何让我们在运行时识别对象和类的信息的?主要有两种方式:
- 一种是传统的RRTI,它假定我们在编译期已知道了所有类型。
- 另一种是反射机制,它允许我们在运行时发现和使用类的信息。
每个类都有一个Class对象,每当编译一个新类就产生一个Class对象(更恰当地说,是被保存在一个同名的.class文件中)。比如创建一个Student类,那么,JVM就会创建一个Student对应Class类的Class对象,该Class对象保存了Student类相关的类型信息。
Class类的对象作用是运行时提供或获得某个对象的类型信息。
如何使用
获取 Class 类对象
获取反射中的Class对象有三种方法。
- 第一种,使用 Class.forName 静态方法。
Class class1 = Class.forName("reflection.TestReflection");
- 第二种,使用类的.class 方法
Class class2 = TestReflection.class;
- 第三种,使用实例对象的 getClass() 方法。
TestReflection testReflection = new TestReflection();
Class class3 = testReflection.getClass();
反射创造对象
通过反射创造对象,获取方法,成员变量,构造器
通过反射创建类对象主要有两种方式:
实例代码:
//方式一
Class class1 = Class.forName("reflection.Student");
Student student = (Student) class1.newInstance();
System.out.println(student);//方式二
Constructor constructor = class1.getConstructor();
Student student1 = (Student) constructor.newInstance();
System.out.println(student1);
运行结果:
反射获取类的构造器
反射获取类的成员变量
反射获取类的方法
反射的应用场景
反射是Java框架的灵魂技术,很多框架都使用了反射技术,如spring,Mybatis,Hibernate等。
JDBC 的数据库的连接
在JDBC连接数据库中,一般包括加载驱动,获得数据库连接等步骤。而加载驱动,就是引入相关Jar包后,通过Class.forName() 即反射技术,加载数据库的驱动程序。
Spring 框架的使用
Spring 通过 XML 配置模式装载 Bean,也是反射的一个典型例子。
装载过程:
- 将程序内XML 配置文件加载入内存中
- Java类解析xml里面的内容,得到相关字节码信息
- 使用反射机制,得到Class实例
- 动态配置实例的属性,使用
这样做当然是有好处的:
不用每次都去new实例了,并且可以修改配置文件,比较灵活。