Java中反射的机制

BingBing-8888 / 2024-10-11 / 原文

反射


目录
  • 反射
    • 反射的概念
    • 反射的作用
    • 反射的原理
      • 直接使用类
      • 使用反射
      • 总结
    • 什么情况下使用反射
    • 反射的优缺点
    • 反射是否真的会让你的程序性能降低?

反射的概念

反射(Reflection)是 Java 的一种特性,它可以让程序在运行时获取自身的信息,并且动态地操作类或对象的属性、方法和构造器等。通过反射功能,可以让我们在不知道具体类名的情况下,依然能够实例化对象,调用方法以及设置属性。

反射的作用

反射的作用有以下几点:

  • 运行时探查类的信息:反射允许我们在运行时加载、检查和使用类,甚至可以在运行时获取一个未加载的类。

  • 动态创建对象:使用反射可以实现动态地创建对象,而且可以选择该类的任意一个构造函数来创建对象实例。

  • 访问或修改私有成员:反射可以访问和修改一个类中私有的字段和方法,即使这些字段和方法是私有的。

  • 扩展应用程序的可控性:反射可以提高应用程序的可扩展性,例如,它可以读取配置文件来决定需要加载哪个类。

反射的原理

直接使用类

正常流程下,我们要创建一个类的实例,是一定确定这个类的类型信息的,我们知道这个类的名字、方法、属性等等。我们可以很容易的创建实例,也可以通过实例很容易的获取属性、调用方法。

使用反射

在一个方法中,如果我们不知道在实际运行(runtime)时,它将要处理的对象是谁,它的类型信息是怎么样的,那我们如何访问这个对象或为这个对象创建一个新的实例呢?

与直接使用类相反,我们需要先获取到对象在方法区的类型信息,获取到类型信息后,我们就知道这个类的构造器、属性、方法、注解、子类、父类等等信息了,这个时候,我们就可以通过这些类型信息来回调处理对象,来完成自己想要的操作了。

没错,这就是反射的原理了。反射在运行时,通过读取方法区中的字节码,来动态的找到其反射的类以及类的方法和属性等(实际上就是在运行时,根据全类型名在方法区找对应的类),用这些类型信息完成对该类实例的操作,其实就是直接使用类的一个逆向使用。

总结

直接使用是在运行前就明确类型信息,然后在运行时根据这个类来操作对象;

而反射是运行时先拿到对象,根据对象得到方法区中的类型信息后,再根据属性、方法来操作该对象。

什么情况下使用反射

Java中的反射机制是指在程序运行时动态获取类的信息以及使用该信息来创建、操作和销毁对象的能力。下面是一些Java中使用反射的情况:

  • 动态加载类:可以使用类加载器动态加载要使用的类,而不是在编译期间声明对该类的依赖关系。

  • 获取类的信息:通过反射可以获取一个类的属性、方法、构造函数等信息,甚至可以获取注解和泛型信息。

  • 通过名称调用方法或访问属性:使用反射可以根据方法/属性名称动态地调用/访问对应的方法/属性,这使得编写通用代码更加容易。

  • 动态代理:使用反射可以实现动态代理,即在运行时动态地创建一个实现某个接口的代理类,从而实现一些特殊的功能,如事务处理等。

需要注意的是,虽然反射提供了很大的灵活性,但过度使用反射会增加代码的复杂性和运行效率,因此应当谨慎使用。

反射的优缺点

优点

  • 增加程序的灵活性,避免将程序写死到代码里。
  • 代码简洁,提高代码的复用率,外部调用方便
  • 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法

缺点

  • 性能问题
  • 使用反射会模糊程序内部逻辑
  • 安全限制
  • 内部暴露

反射是否真的会让你的程序性能降低?

1.反射大概比直接调用慢50~100倍,但是需要你在执行100万遍的时候才会有所感觉

2.判断一个函数的性能,你需要把这个函数执行100万遍甚至1000万遍

3.如果你只是偶尔调用一下反射,请忘记反射带来的性能影响

4.如果你需要大量调用反射,请考虑缓存。

5.你的编程的思想才是限制你程序性能的最主要的因素