目录
面试回答
知识扩展
反射常见的使用方式
反射和 Class 的关系
面试回答
反射指的是程序在运行时能够获取自身的信息。在 java 中,只要给定类的名字,那么就可以通过反射机制来获得类的所有属性和方法。
Java 的反射可以:
- 在运行时判断任意一个对象所属的类
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时任意调用一个对象的方法
- 在运行时构造任意一个类的对象
反射的好处就是可以提升程序的灵活性和扩展性,比较容易在运行期干很多事情。但是他带来的问题更多,主要有以下几个:
- 代码可读性低及可维护性
- 反射代码执行的性能低
- 反射破坏了封装性
所以,我们应该在业务代码中应该尽量避免使用反射。但是,作为一个合格的 Java 开发,也要能读懂中间件、框架中的反射代码。在有些场景下,要知道可以使用反射解决部分问题。
那么,反射为什么慢呢?主要由以下几个原因:
- 由于反射涉及动态解析的类型,因此不能执行某些 Java 虚拟机优化,如 JIT 优化。
- 在使用反射时,参数需要包装(boxing)成 Object[] 类型,但是真正方法执行胡时候,又需要再拆包(unboxing)成真正的类型,这些动作不仅消耗时间,而且过程中也会产生很多对象,对象一多就容易导致 GC,GC 也会导致应用变慢。
- 反射调用方法时会从方法数组中遍历查找,并且会检查可见性。这些动作都是耗时的。
- 不仅方法的可见性要做检查,参数也需要做很多额外的检查。
知识扩展
反射常见的使用方式
- 动态代理
- JDBC 的 class.forName
- BeanUtils 中属性值的拷贝
- RPC 框架
- ORM 框架
- Spring 的 OC/DI
反射和 Class 的关系
Java 的 Class 类是 java 反射机制的基础,通过 Class 类我们可以获得关于一个类的相关信息。
Java.lang.Class 是一个比较特殊的类,它用于封装被装入到 JVM 中的类(包括类和接口)的信息。当一个类或接口被装入的 JVM 时便会产生一个与之关联的 java.lang.Class 对象,可以通过这个 Class 对象对被装入类的详细信息进行访问。
虚拟机为每种类型管理一个独一无二的 Class 对象。也就是说,每个类(型)都有一个 Class 对象。运行程序时,Java 虚拟机(JVM)首先检查所要加载的类对应的 Class 对象是否已经加载。如果没有加载,JVM 就会根据类名查找 .class 文件,并将其 Class 对象载入。