反射
反射机制是 Java 赋予程序在运行时自省(introspect)的能力,可以操作运行时才能确定的信息。在运行时动态获取类和类成员定义,以及动态读取属性调用方法或构造对象,甚至可以运行时修改类定义。针对类动态调用方法,不管类中字段和方法怎么变动,都可以用相同的规则来读取信息和执行方法。几乎所有的ORM(对象关系映射)、对象映射、MVC框架都使用了反射。
注:相信熟悉Java的一定听过这么一句话,Java是静态的强类型语言,但因为提供反射等机制,也具备了部分动态类型语言的能力。动态/静态区别在运行时检查,还是编译期检查;强/弱类型区别在不同类型变量赋值时是否需要显式地(强制)进行类型转换。
java.lang 或 java.lang.reflect 包源码抽象会让你对 Java 反射有一个很直观的印象。Class、Field、Method、Constructor等元素可以去操作类和对象的元数据,反射的起点是Class类,Class类提供了各种方法去查询它的信息,参考反射官方文档和java.lang.Class<T>。
反射调用方法遇到重载的case
(使用反射时的误区),往往认为反射调用方法还是根据入参确定方法重载(反射调用方法不是以传参决定重载)。
// 有两个名字都叫num的方法,入参分别是原始数据类型int和包装类型Integer。
@Slf4j
public class SoraApplication {
private void num(int n) {
log.info("int num = {}", n);
}
private void num(Integer n) {
log.info("Integer num = {}", n);
}
}
// 不用反射,走哪个重载方法很清晰
SoraApplication application = new SoraApplication();
// 16:31:52.103 [main] INFO sora.example.instances.ReflectionTest - int num = 100
application.num(100);
// 16:31:52.108 [main] INFO sora.example.instances.ReflectionTest - Integer num = 100
application.num(Integer.valueOf("100"));
// 使用 getDeclaredMethod 获取 num 方法,然后传入Integer.valueOf(“10