Class
类提供了以下几个方法来获取Method
:
下面给出两个简单的示例:
public static <T> void getDeclaredMethods(T t) { Object obj = (Object) t; Class cls = obj.getClass(); Method[] methods = cls.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { System.out.println(methods[i]); } }
public static <T> void getMethod(T t) throws NoSuchMethodException { Object obj = (Object) t; Class cls = obj.getClass(); System.out.println(cls.getMethod("setName", String.class)); System.out.println(cls.getMethod("getName")); }
像Field
对象包含了一个字段的所有信息一样,Method
对象也包含一个方法的所有信息,下面简单介绍几个常用的方法:
getName()
:返回方法名称;getReturnType()
:返回方法返回值类型,也是一个Class
实例;getParameterTypes()
:返回方法的参数类型,是一个Class
数组,例如:{String.class, int.class}
;示例:
public static <T> void getMethodReturnType(T t) throws NoSuchMethodException { Object obj = (Object) t; Class cls = obj.getClass(); Method method = cls.getMethod("setName", String.class); System.out.println(method.getName()); // setName System.out.println(method.getReturnType()); // void Class<?>[] p = method.getParameterTypes(); for (int i = 0; i < p.length; i++) { System.out.println(p[i]); // class java.lang.String } }
下面给出一个具体的调用substring
方法的示例:
public static void getSubstringMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { String str = "Happy-new-year"; // 获取String substring(int, int)方法: Method m = String.class.getMethod("substring", int.class, int.class); // 在s对象上调用该方法并获取结果: String r = (String) m.invoke(str, 2, 5); // 打印调用结果: System.out.println(r); }
调用Method
实例的invoke
方法就相当于调用该方法。invoke的第一个参数是要调用的对象实例(此处substring
是要对str
使用,所以传入str
),后续为可变参数,要与调用方法的参数保持一致。
有一些特殊的方法,情况稍有不同。
假如调用的方法为static
方法,因为不需要指定调用的实例对象,所以invoke
的第一个参数需设置为null
。
假如调用的方法为private
或者protect
方法。需要采取和访问私有Field
的一样的方法:在使用invoke
方法之前,需设置Method.setAccessible(true)
。
假如某一方法在父类中存在,同时在子类中也进行了重写,即存在多态的情况。使用invoke
调用同样支持多态原则,会根据传入invoke
方法的第一个参数的实际类型来进行调用。