被测试类
TestMethod.java
package cn.reflect;
public class TestMethod {
public void test() {
System.out.println("---------");
}
public String meth() {
return "hello";
}
public static String meo() {
return "wsm";
}
public String tests(String s){
System.out.println("++++++++++");
return s;
}
}
测试类
package cn.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflection {
public static void main(String[] args) throws ClassNotFoundException,
SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class c = null;
c = cl.loadClass("cn.reflect.TestMethod");
Method[] m = c.getMethods();
//第一个参数是方法名 第二个参数是tests方法形式参数的类型,对于多个形式参数,会有多个类型,他们共同组成一个Class[]数组,对于tests方法,只有一个参数
Method method = c.getMethod("tests", new Class[]{String.class});
// for (int i = 0; i < m.length; i++) {
// // 输出方法的返回类型
// System.out.print(m[i].getReturnType().getName());
// // 输出方法名
// System.out.print(" " + m[i].getName() + "(");
// // 获取方法的参数
// Class[] parameterTypes = m[i].getParameterTypes();
// for (int j = 0; j < parameterTypes.length; j++) {
// System.out.print(parameterTypes[j].getName());
// if (parameterTypes.length > j + 1) {
// System.out.print(",");
// }
// }
//
// System.out.println(")");
// }
Object o = null;
//第一个参数是TestMethod类的实例对象 第二个参数是tests方法的参数,参数可能有多个,他们共同组成一个Object数组
o = method.invoke(c.newInstance(), new Object[] {new String("asjdflkajglkjadsflk")});
System.out.println(o);
}
}
另:附Class.getMethod方法说明
getMethod
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
- 返回一个
Method
对象,它反映此Class
对象所表示的类或接口的指定公共成员方法。name
参数是一个String
,用于指定所需方法的简称。parameterTypes
参数是按声明顺序标识该方法形参类型的Class
对象的一个数组。如果parameterTypes
为null
,则按空数组处理。如果
name
是 "<init>
;" 或 "<clinit>
",则将引发NoSuchMethodException
。否则,要反映的方法由下面的算法确定(设 C 为此对象所表示的类):- 在 C 中搜索任一匹配的方法。如果找不到匹配的方法,则将在 C 的超类上递归调用第 1 步算法。
- 如果在第 1 步中没有找到任何方法,则在 C 的超接口中搜索匹配的方法。如果找到了这样的方法,则反映该方法。
注意,类中可以有多个匹配方法,因为尽管 Java 语言禁止类声明带有相同签名但不同返回类型的多个方法,但 Java 虚拟机并不禁止。这增加了虚拟机的灵活性,可以用来实现各种语言特性。例如,可以使用桥方法 (brige method)实现协变返回;桥方法以及将被重写的方法将具有相同的签名,不同的返回类型。
请参阅Java 语言规范 第 8.2 和 8.4 节。
-
-
- 参数:
name
- 方法名parameterTypes
- 参数列表- 返回:
- 与指定的
name
和parameterTypes
匹配的Method
对象 - 抛出:
NoSuchMethodException
- 如果找不到匹配的方法,或者方法名为 "<init>" 或 "<clinit>"NullPointerException
- 如果name
为null
SecurityException
- 如果存在安全管理器 s,并满足下列任一条件:- 调用
s.checkMemberAccess(this, Member.PUBLIC)
拒绝访问方法 - 调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对
s.checkPackageAccess()
的调用拒绝访问该类的包
- 调用
- 从以下版本开始:
- JDK1.1
还有Method.invoke方法说明
invoke
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
- 对带有指定参数的指定对象调用由此
Method
对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。如果底层方法是静态的,那么可以忽略指定的
obj
参数。该参数可以为 null。如果底层方法所需的形参数为 0,则所提供的
args
数组长度可以为 0 或 null。如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。
如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。
如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。
-
-
- 参数:
obj
- 从中调用底层方法的对象args
- 用于方法调用的参数- 返回:
- 使用参数
args
在obj
上指派该对象所表示方法的结果 - 抛出:
IllegalAccessException
- 如果此Method
对象强制执行 Java 语言访问控制,并且底层方法是不可访问的。IllegalArgumentException
- 如果该方法是实例方法,且指定对象参数不是声明底层方法的类或接口(或其中的子类或实现程序)的实例;如果实参和形参的数量不相同;如果基本参数的解包转换失败;如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。InvocationTargetException
- 如果底层方法抛出异常。NullPointerException
- 如果指定对象为 null,且该方法是一个实例方法。ExceptionInInitializerError
- 如果由此方法引起的初始化失败。