什么是java反射?
Java反射(Reflection)是Java编程语言的一个强大特性,它允许程序在运行时访问和操作类、接口、字段、方法等的元数据。反射API提供了一组类和方法,使得程序能够查询和使用类的信息,以及在运行时动态地创建对象、调用方法、访问字段等。
使用Java反射,你可以实现以下功能:
- 在运行时获取类的信息:可以通过Class类或Class.forName()方法获取类的Class对象,然后查询类的定义信息,如类名、父类、实现的接口、构造函数、字段和方法等。
- 动态创建对象实例:使用Class对象的newInstance()方法可以创建类的实例,即使在编译时不知道具体的类名。
- 动态调用方法:可以通过Method对象的invoke()方法动态地调用对象的方法,无论这些方法是公共的、受保护的、默认的还是私有的。
- 动态访问和修改字段:使用Field对象可以动态地读取或修改对象的字段值,无论字段的访问权限如何。
- 创建代理对象:利用InvocationHandler和Proxy类,可以在运行时创建接口的代理实例,而无需在编译时定义具体的实现类。
示例
1 | import java.lang.reflect.InvocationTargetException; |
简化写法
1 | Class clazz = Class.forName("java.lang.Runtime"); |
getMethod
在Java中,getMethod是java.lang.Class类的一个方法,它用于在运行时获取类中特定名称和参数类型的Method对象。这个Method对象代表了类中的一个方法。
getMethod 的作用是通过反射获取一个类的某个特定的公有方法。使用getMethod方法,你可以在运行时动态地调用一个对象的方法,即使在编译时你不知道具体要调用哪个方法。getMethod方法有几种重载形式,最常见的两种是:
- getMethod(String name):通过方法名获取一个无参方法。
- getMethod(String name, Class<?>… parameterTypes):通过方法名和参数类型数组获取一个方法。
我们使用最简单的,也就是第一个,它只有一个参数,类型是String,所以我们使用 getMethod(“exec”, String.class) 来获取 Runtime.exec 方法。
这个例子中我们首先获取了String类的Class对象,然后使用getMethod方法获取了getRuntime方法的Method对象。最后,我们通过invoke方法动态地调用了exec()方法,并打印了结果。
invoke
在Java中,invoke方法是java.lang.reflect.Method类的一个方法,它用于动态调用一个对象的方法。这个方法是Java反射机制的一部分,允许程序在运行时确定和调用方法,而不需要在编译时硬编码方法的调用。
invoke方法的基本语法如下:
1 | public Object invoke(Object obj, Object... args) |
- obj 参数是要在其上调用方法的对象。如果方法是一个静态方法,那么这里传入的是类本身(Class 对象)。
- args 参数是一个可变参数,包含了要传递给方法的参数。如果调用的方法不需要参数,这里可以传入一个空数组。
invoke 方法可能会抛出几个异常:
- IllegalAccessException:如果方法不可访问,比如它是私有的。
- InvocationTargetException:如果方法本身抛出了异常,这个异常会被封装在InvocationTargetException中。可以通过调用getCause方法来获取原始的异常。
- IllegalArgumentException:如果传递给invoke的参数不正确,比如参数数量不匹配或者类型不兼容。
使用例子如下:
1 | import java.lang.reflect.Method; |
我们首先通过getMethod获取了MyClass的add方法和staticMethod方法的Method对象。然后,我们使用invoke方法分别调用了这两个方法,并打印了结果。对于staticMethod,我们传入null作为第一个参数,因为静态方法不需要对象实例就可以调用。