反射 Reflection
指的是 Java
程序在运行期可以获取自身的信息,并且可以操作类或对象的内部属性。
反射使 Java
代码可以发现有关已加载类的字段,方法和构造函数信息,并在安全性限制内操作这些字段,方法和构造函数。
反射的核心是 JVM
在运行时才动态加载类或调用方法或访问属性,它不需要事先知道运行对象是谁。
反射的主要功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时得到任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的所有方法。
反射常见用途:
- 最重要的用途就是开发各种通用框架,通过配置文件(如
XML
等)加载不同的类或对象,调用不同的方法,运行时动态加载不同的对象;- 写测试用例的时候不能改动原有代码中的私有属性,可以通过反射来调用一些
private
方法和字段;- 其实我们平时用
IDE
写代码时,当我们输入一个对象或类并想调用它的属性或方法时,点号后就会自动列出它的属性或方法,这里就用到了反射。
三种获取方法:
- Class cls = String.class;
- String s = "Hello"; Class cls = s.getClass();
- Class cls = Class.forName("java.lang.String");
JVM
在执行 Java
程序的时候,并不是一次性把所有用到的 class
全部加载到内存,而是第一次需要用到 class
时才加载。
public class Main {
public static void main(String[] args) {
if (args.length > 0) {
create(args[0]);
}
}
static void create(String name) {
Person p = new Person(name);
}
}
对于上面的这段代码,当执行 Main.java
时,JVM
首先会把 Main.class
加载到内存。
然而,并不会加载 Person.class
,除非程序执行到 create()
方法,JVM
发现需要加载 Person
类时,才会首次加载 Person.class
。
如果没有执行 create()
方法,那么 Person.class
根本就不会被加载。
这就是 JVM
动态加载 class 的特性。
动态加载 class 的特性对于 Java 程序非常重要。利用 JVM
动态加载 class 的特性,我们才能在运行期根据条件加载不同的实现类。
例如,Commons Logging
总是优先使用 Log4j
,只有当 Log4j
不存在时,才使用 JDK 的 logging
。
获取四种方法:
- Field getField(name):根据字段名获取某个public的field(包括父类)
- Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
- Field[] getFields():获取所有public的field(包括父类)
- Field[] getDeclaredFields():获取当前类的所有field(不包括父类)
获取四种方法:
- getConstructor(Class...):获取某个public的Constructor
- getDeclaredConstructor(Class...):获取某个Constructor
- getConstructors():获取所有public的Constructor
- getDeclaredConstructors():获取所有Constructor
获取四种方法:
- Method getMethod(name, Class...):获取某个public的Method(包括父类)
- Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)
- Method[] getMethods():获取所有public的Method(包括父类)
- Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)
要求:在不改变原来类任意代码的情况下,可以创建任意类对象并执行任意方法。
通过配置文件和反射机制来实现。
优点:在使用一些框架时,不能修改框架里的代码,如果用 new
的方式来实例化对象,在重构时会很繁琐,若仅仅只是修改配置文件就会简单的多。
而且用反射还能达到解耦的效果:若用 new
方式来实例化对象,当该类丢失时编译期间就会报错导致整个项目无法启动;而用反射创建对象,在编译期间仅需要类名字符串,不会报错,不影响其他模块的正常运行。
这也是 Spring
框架中 IOC
控制反转的本质。