关于Java反射的疑问

一直很安静 发布于 2013/04/26 13:32
阅读 301
收藏 1

近期在看java的反射,产生一些疑问,想询问下。

通过反射,拿到一个字节码文件的所有public类型的方法,然后调用方法,如果是有参数的方法,怎么去构造函数所对应的类型参数?并传递参数调用函数?

如:

public void add(String str,int x){
     System.out.println(str+x);
}
上面的函数,通过反射获Method对象后,怎么通过其参数类型,传递参数并调用啊?(假设调用者不知道这个函数的参数类型),完全通过反射得到参数类型,然后根据参数类型去构造实参调用。

加载中
0
NotFoundException
NotFoundException
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class MethodInvokeTest {

	/**
	 * 
	 * @param 对象类
	 * @param methodName
	 * @param 参数值
	 * @return
	 */
	public Object InvokeMethod(String clsName, String methodName,
			Object... value) {
		Object returnValue = null;
		Object obj = null;
		try {
			Class cls = Class.forName(clsName);
			obj = cls.newInstance();
			Method[] DeclaredMethods = cls.getDeclaredMethods();
			for (Method method : DeclaredMethods) {
				String methodScope = method.toGenericString();
				String publicMethod = methodScope.split(" ")[0];
				// 如果是公共的方法
				if (publicMethod.equals("public")) {
					// 参数类型
					Type[] types = method.getGenericParameterTypes();

					// 参数值
					if (types.length > 0) {
						for (int i = 0; i < types.length; i++) {
							System.out.println(types[i]);
						}
						returnValue = method.invoke(obj, value);
					} else {
						returnValue = method.invoke(obj);
					}
				} else
					continue;
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			System.out.println("参数类型不匹配。。。");
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		return returnValue;
	}

	public static void main(String[] args) {
		String returnValue = ((String) new MethodInvokeTest().InvokeMethod(
				"User", "add", "zhoushunde", 5));
		System.out.println(returnValue);

	}

add方法

public class User {

	 
	/**
	 * @param username
	 *           	 */
	public String  add(String username, int id) {
		return username+":"+id;
	}

}

 

结果:

第1个参数为class java.lang.String
第2个参数为int
zhoushunde:5

如果实参类型与形参类弄不匹配就会在异常中提示的

NotFoundException
NotFoundException
哦,还有这个方法呀,多谢提醒
le284
le284
if(Modifier.isPublic(m.getModifiers())) 判断方法是否为public
0
逝水fox
逝水fox

getParameterTypes()和invoke() 详情自己查OSC提供的API文档

0
一直很安静
一直很安静

感谢  逝水fox  的回答,我翻看过API文档,方法getParameterTypes() 返回的是方法的形参类型。Class<?> [] ,但是这个我也只能确定参数类型,而我疑惑的地方是,我确定了类型,怎么去构造实参数据?

比如:我通过这个,确定了第一个是参数是String,第二个是int,而从程序角度,得到的是其字节码对象,而我想的是,假设通过这个,知道了是Stirng,我就创建一个String字符串,第二个是int,我就给一个数字,难道这里只能做判断了?不能做成通用的?万一参数是自定义类型呢?比如Student类型呢?

逝水fox
逝水fox
问题是,如果你连参数是什么数据都不知道,这种调用函数和除了基本类型全部null的传参有什么区别...
0
飞敛
应该是尝试强制转换值。若不能转就抛异常。这是我工作中strust遇到问题的想法。strust反射目标若发现目标值不对。就会出错。其他不清楚。未做过具体实验
0
一直很安静
一直很安静

那按照你的意思就是说,他应该对这个参数还是有一个限制范围的,如果可以将其参数强制转换成目标参数类型,就可以调用,如果无法强制转换成目标函数参数类型,就报错?


0
一直很安静
一直很安静
感谢各位的热心帮助,总算明白了。。谢谢。
返回顶部
顶部