什么是反射?
反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息。
什么是反射
正常情况下,如果我们要调用一个对象的方法,或者访问一个对象的字段,通常会传入对象实例:1
2
3
4
5
6
7
8// Main.java
import com.itranswarp.learnjava.Person;
public class Main {
String getFullName(Person p) {
return p.getFirstName() + " " + p.getLastName();
}
}
但是,如果不能获得Person类,只有一个Object实例,比如这样:1
2
3String getFullName(Object obj) {
return ???
}
如何调用?
怎么办?有童鞋会说:强制转型啊!1
2
3
4String getFullName(Object obj) {
Person p = (Person) obj;
return p.getFirstName() + " " + p.getLastName();
}
强制转型的时候,你会发现一个问题:编译上面的代码,仍然需要引用Person类。不然,去掉import语句,你看能不能编译通过?所以,反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法。
JVM为每个加载的class及interface创建了对应的Class实例来保存class及interface的所有信息;获取一个class对应的Class实例后,就可以获取该class的所有信息;
通过Class实例获取class信息的方法称为反射(Reflection);JVM总是动态加载class,可以在运行期根据条件来控制加载class。
动态加载class的特性对于Java程序非常重要。利用JVM动态加载class的特性,我们才能在运行期根据条件加载不同的实现类。例如,Commons Logging总是优先使用Log4j,只有当Log4j不存在时,才使用JDK的logging。利用JVM动态加载特性,大致的实现代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// Commons Logging优先使用Log4j:
LogFactory factory = null;
if (isClassPresent("org.apache.logging.log4j.Logger")) {
factory = createLog4j();
} else {
factory = createJdkLog();
}
boolean isClassPresent(String name) {
try {
Class.forName(name);
return true;
} catch (Exception e) {
return false;
}
}