✅什么是反射机制?为什么反射慢?

典型回答

反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有属性和方法。

Java的反射可以:

  1. 在运行时判断任意一个对象所属的类。
  2. 在运行时判断任意一个类所具有的成员变量和方法。
  3. 在运行时任意调用一个对象的方法
  4. 在运行时构造任意一个类的对象

Object obj = // ... 任意对象;
Class<?> clazz = obj.getClass();

// 获取成员变量
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
    System.out.println("成员变量: " + field.getName());
}

// 获取方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
    System.out.println("方法: " + method.getName());
}


Method method = clazz.getDeclaredMethod("methodName", // 方法参数类型...);
method.setAccessible(true); // 如果方法是私有的
method.invoke(obj, // 方法参数...);


// 默认构造函数
Object obj = clazz.newInstance();

// 或者使用特定的构造函数
Constructor<?> constructor = clazz.getConstructor(// 参数类型...);
Object obj = constructor.newInstance(// 构造函数参数...);

反射的好处就是可以提升程序的灵活性和扩展性,比较容易在运行期干很多事情。但是他带来的问题更多,主要由以下几个:

1、代码可读性低及可维护性

2、反射代码执行的性能低

3、反射破坏了封装性

所以,我们应该在业务代码中应该尽量避免使用反射。但是,作为一个合格的Java开发,也要能读懂中间件、框架中的反射代码。在有些场景下,要知道可以使用反射解决部分问题。

那么,反射为什么慢呢?主要由以下几个原因:

1、由于反射涉及动态解析的类型,因此不能执行某些Java虚拟机优化,如JIT优化。

2、在使用反射时,参数需要包装(boxing)成Object[] 类型,但是真正方法执行的时候,又需要再拆包(unboxing)成真正的类型,这些动作不仅消耗时间,而且过程中也会产生很多对象,对象一多就容易导致GC,GC也会导致应用变慢。

3、反射调用方法时会从方法数组中遍历查找,并且会检查可见性。这些动作都是耗时的。

4、不仅方法的可见性要做检查,参数也需要做很多额外的检查。

扩展知识

反射常见的应用场景

  1. 动态代理
  2. JDBC的class.forName
  3. BeanUtils中属性值的拷贝
  4. RPC框架
  5. ORM框架
  6. Spring的IOC/DI

反射和Class的关系

Java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息

Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息。当一个类或接口被装入到JVM时便会产生一个与之关联的java.lang.Class对象,可以通过这个Class对象对被装入类的详细信息进行访问。

虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。

反射破坏单例

✅如何破坏单例模式?

原文: https://www.yuque.com/hollis666/xkm7k3/sr19rp