java.lang.reflect.Method 类,java反射机制提供的对方法的操作。
获取 Method 实例
方法的封装类为Method,Class类提供了以下四个方法来获取Field对象:
public Method[] getMethods()
:获取所有的public方法,包括继承来的方法public Method getMethod(String name,Class<?>...parameterTypes)
:根据方法名获取指定的public方法public Method[] getDeclaredMethods()
:获取所有声明的方法(本类方法,不包括继承)public Method getDeclaredMethod(String name,Class<?>...parameterTypes)
:根据方法名获得指定的方法, 参数name为方法名,参数 parameterTypes 为方法的参数类型
注意:获取带参数方法时,如果参数类型错误会报 NoSuchMethodException ,对于参数是泛型的情况,泛型须当成Object处理(Object.class)
**
Method 的常用方法
java.lang.reflect.Modifier 有一个 public static String toString(int mod) 方法,能够将获取的 int 修饰符转换成可以阅读的字符串
- 获取方法的修饰符:public int getModifiers()
- 获取方法名称:public String getName()
- 获取方法的参数个数:public int getParameterCount()
- 执行方法:public Object invoke(Object obj, Object… args)
参数说明:
- Object obj:执行该方法的实例
- Object… args:方法参数
- 获取方法的返回类型:
public Class<?> getReturnType()
:获取目标方法返回类型对应的 Class 对象public Type getGenericReturnType()
:获取目标方法返回类型对应的 Type 对象
区别:
- getReturnType() 返回类型为Class,getGenericReturnType()返回类型为Type ; Class实现Type
- 返回值为普通简单类型如 Object, int, String 等,getGenericReturnType()返回值和getReturnType()一样
- 返回值为泛型:例如
public T function2()
那么各自返回值为:getReturnType() : class java.lang.Object
getGenericReturnType() : T
- 返回值为参数化类型:例如
public Class<String> function3()
,那么各自返回值为:getReturnType() : class java.lang.Class
getGenericReturnType() : java.lang.Class<java.lang.String>
- 取得方法的参数类型:区别同上
- public Class<?>[] getParameterTypes():获取目标方法各参数类型对应的Class对象
- public Type[] getGenericParameterTypes():获取目标方法各参数类型对应的Type对象
- 获取方法声明抛出的异常的类型:区别同上
- getExceptionTypes():获取目标方法抛出的异常类型对应的Class对象
- getGenericExceptionTypes():获取目标方法抛出的异常类型对应的Type对象
- 获取方法参数名称:
- .class文件中默认不存储方法参数名称,如果想要获取方法参数名称,需要在编译的时候加上
-parameters
参数。(构造方法的参数获取方法同样)- 判断方法参数是否为可变参数:method.isVarArgs()
通过反射调用方法的步骤
// 1. 获取 Class 对象
Class<?> clazz = Class.forName("top.songfang.reflect.User");
// 2. 通过 Class 对象创建实例
User user = (User) clazz.getDeclaredConstructor().newInstance();
// 3. 获取 Method 对象
Method method = clazz.getDeclaredMethod("print", String.class);
// 4. 设置访问权限
method.setAccessible(true);
// 5. 调用
method.invoke(user,"世界");
注意事项:
- Method.invoke(Object obj, Object… args) 方法中第一个参数为需要调用的目标类对象,如果方法为 static 的,则该参数为 null。后面的参数都为目标方法的参数值,顺序与目标方法声明中的参数顺序一致。
- 如果方法是private的,可以使用method.setAccessible(true)方法绕过权限检查
- 被调用的方法本身所抛出的异常在反射中都会以
InvocationTargetException
抛出。换句话说,反射调用过程中如果异常InvocationTargetException
抛出,说明反射调用本身是成功的,因为这个异常是目标方法本身所抛出的异常。