java.lang.reflect.Method 类,java反射机制提供的对方法的操作。

获取 Method 实例

方法的封装类为Method,Class类提供了以下四个方法来获取Field对象:

  1. public Method[] getMethods():获取所有的public方法,包括继承来的方法
  2. public Method getMethod(String name,Class<?>...parameterTypes):根据方法名获取指定的public方法
  3. public Method[] getDeclaredMethods():获取所有声明的方法(本类方法,不包括继承)
  4. 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 修饰符转换成可以阅读的字符串

  1. 获取方法的修饰符:public int getModifiers()
  2. 获取方法名称:public String getName()
  3. 获取方法的参数个数:public int getParameterCount()
  4. 执行方法:public Object invoke(Object obj, Object… args)

参数说明:

  • Object obj:执行该方法的实例
  • Object… args:方法参数
    1. 获取方法的返回类型:
  • 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>
      1. 取得方法的参数类型:区别同上
  • public Class<?>[] getParameterTypes():获取目标方法各参数类型对应的Class对象
  • public Type[] getGenericParameterTypes():获取目标方法各参数类型对应的Type对象
    1. 获取方法声明抛出的异常的类型:区别同上
  • getExceptionTypes():获取目标方法抛出的异常类型对应的Class对象
  • getGenericExceptionTypes():获取目标方法抛出的异常类型对应的Type对象
    1. 获取方法参数名称:
  • .class文件中默认不存储方法参数名称,如果想要获取方法参数名称,需要在编译的时候加上-parameters参数。(构造方法的参数获取方法同样)
    1. 判断方法参数是否为可变参数:method.isVarArgs()

通过反射调用方法的步骤

  1. // 1. 获取 Class 对象
  2. Class<?> clazz = Class.forName("top.songfang.reflect.User");
  3. // 2. 通过 Class 对象创建实例
  4. User user = (User) clazz.getDeclaredConstructor().newInstance();
  5. // 3. 获取 Method 对象
  6. Method method = clazz.getDeclaredMethod("print", String.class);
  7. // 4. 设置访问权限
  8. method.setAccessible(true);
  9. // 5. 调用
  10. method.invoke(user,"世界");

注意事项:

  1. Method.invoke(Object obj, Object… args) 方法中第一个参数为需要调用的目标类对象,如果方法为 static 的,则该参数为 null。后面的参数都为目标方法的参数值,顺序与目标方法声明中的参数顺序一致。
  2. 如果方法是private的,可以使用method.setAccessible(true)方法绕过权限检查
  3. 被调用的方法本身所抛出的异常在反射中都会以InvocationTargetException抛出。换句话说,反射调用过程中如果异常InvocationTargetException抛出,说明反射调用本身是成功的,因为这个异常是目标方法本身所抛出的异常。