JAVA反射练习
题目
实现一个方法
public static Object execute(String className, String methodName, Object args[])
实现 “通过类的名字、方法名字、方法参数调调用方法,返回值为该方法的返回值。” 的功能。
解题思路
开始阶段
一开始看到这个题目,以为很简单。大致思路就是通过反射获取字节码文件对象,然后该对象获取方法名的方法对象。
将args数组转换成Class对象数组,这样来获取具体的调用某一个方法,最后调用invoke(obj,args)方法完成。
发现问题
按照这个思路写出程序,如下所示:
public static Object execute(String className, String methodName,Object[] args) throws Exception {
// 获取类的字节码文件对象
Class cls = Class.forName(className);
// 获取方法调用的参数的Class对象
Class[] paramsCls = new Class[args.length];
for (int i = 0; i < args.length; i++) {
paramsCls[i] = args[i].getClass();
}
// 获取方法对象
Method method = cls.getMethod(methodName, paramsCls);
Object obj = cls.newInstance();
return method.invoke(obj,args);
}
乍一看,这个程序没有什么太大的问题,可是在测试这个方法时出现了问题,如测试一个public int add(int a,int b)。在传递参数时,是一个Object类型的数组,如20,30这两个参数在传递过去时就被自动的装箱成为了Integer类型。那么获取的Class对象就成为了 class java.lang.Integer,但是add方法的参数却是int类型。
一开始我以为没什么问题,但是在调用cls.getMethod()方法时,出现了问题。虚拟机抛出异常,表示没有这样的方法,这让我很困惑,后来百度了一下,发现int.class和Integer.class并不能混为一谈,也就是这两者并不能像自动拆装箱那样进行转换。也明白了C