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.ObjectgetGenericReturnType() : T
- 返回值为参数化类型:例如
public Class<String> function3(),那么各自返回值为:getReturnType() : class java.lang.ClassgetGenericReturnType() : 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抛出,说明反射调用本身是成功的,因为这个异常是目标方法本身所抛出的异常。
