怎样在反射里正确识别基础类型?如int

横云断岭
博客专家认证
2011-10-28 02:28:01
我想写这么个函数:
参数:传进一个对象o,这个对象要被调用的方法o.func,这个方法的参数列表 args
返回:方法执行的结果,即return o.func(args)

public Object callObjectMethod(Object o, String methodName, Object...args)


我自已写了个,但是有很个问题,不能识别基本类型,比如有个对象o,它有个函数void func(int i), 我调用callObjectMethod(o, "func", 123),在实际上会尝试调用void func(Integer i)。这样就会抛出找不到方法的异常。
因为callObjectMethod把123转为一个Integer了。
去看了下MessagePack的做法,它居然是据Method名字来判断调用那个函数的,也就是说如果有同名的函数,后面的会覆盖前面的函数。。

public Object callObjectMethod(Object o, String methodName, Object...args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
Class<?> class1 = o.getClass();
Class[] methodArgs = null;
if(args != null){
methodArgs = new Class[args.length];
for(int i = 0; i < args.length; ++i)
methodArgs[i] = args[i].getClass();
}

Method method = class1.getMethod(methodName, methodArgs);
return method.invoke(o, args);
}

请问怎样实现??
...全文
482 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
横云断岭 2012-02-23
  • 打赏
  • 举报
回复
原来是没有把参数列表传进去。

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Hello {
public String hello(String s){
return "String hello(String s):" + s;
}
public String hello(int i){
return "String hello(int i):" + i;
}
}
public class Test {
public static Object test(Object o, String methodName, Class<?>[] arguments, Object ...objects) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
Method method = o.getClass().getMethod(methodName, arguments);
Object invoke = method.invoke(o, objects);
return invoke;
}

public static void main(String[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Hello hello = new Hello();
Class<?>[] c = {String.class};
System.out.println(test(hello, "hello", c, "abc"));
System.out.println(test(hello, "hello", new Class<?>[] {int.class}, 100));
}
}



http://javatar.iteye.com/blog/1123915
lliiqiang 2011-10-28
  • 打赏
  • 举报
回复
java基本数据类型对应的引用类型都有一个TYPE静态属性.
例如Integer.TYPE是代表基本int数据类型
例如有一个sub(int i)的方法,如果想反射调用

Method method = class1.getMethod("sub",Integer.TYPE);
若鱼1919 2011-10-28
  • 打赏
  • 举报
回复
int.class != Integer.class
wula0010 2011-10-28
  • 打赏
  • 举报
回复
我的反射里是这样做的:

Class[] parameter = method.getParameterTypes();
Object[] args = new Object[parameter.length];

for (int j = 0; j < parameter.length; j++) {
try {
if (parameter[j] == Map.class) {
args[j] = (Map) paraList.get(j);
}else if (parameter[j] == HashMap.class) {
args[j] = (HashMap) paraList.get(j);
}else if (parameter[j] == List.class) {
args[j] = (List) paraList.get(j);
}else if (parameter[j] == ArrayList.class) {
args[j] = (ArrayList) paraList.get(j);
}else if (parameter[j] == HttpServletRequest.class) {
args[j] = (HttpServletRequest) request;
} else if (parameter[j] == HttpServletResponse.class) {
args[j] = (HttpServletResponse) response;
}
} catch (Exception e) {
//返回错误,数据类型错误=========================================
throw new AppException(ajaxBean + "的参数和传入的参数类型不符。参数序号:" + ((Integer) j).toString() + ",参数类型:" + parameter[j].toString() + ",传入类型:" + paraList.get(j).getClass());
}

if (parameter[j] == String.class || parameter[j] == Boolean.class || parameter[j] == boolean.class || parameter[j] == Integer.class || parameter[j] == int.class || parameter[j] == float.class || parameter[j] == Float.class || parameter[j] == double.class || parameter[j] == Double.class || parameter[j] == Date.class) {
Object value = paraList.get(j);

if (parameter[j] == Integer.class || parameter[j] == int.class) {
if (value instanceof Integer) {
args[j] = value;
} else if (value instanceof Float) {
args[j] = ((Float) value).intValue();
} else if (value instanceof Double) {
args[j] = ((Double) value).intValue();
} else if (value instanceof String) {
args[j] = Integer.valueOf((String) value).intValue();
} else {
//返回错误,数据类型错误=========================================
throw new AppException(ajaxBean + "的参数和传入的参数类型不符。参数序号:" + ((Integer) j).toString() + ",参数类型:Integer,传入类型:" + value.getClass());
}
} else if (parameter[j] == float.class || parameter[j] == Float.class) {
if (value instanceof Float) {
args[j] = value;
} else if (value instanceof Integer) {
args[j] = (Float) value;
} else if (value instanceof Double) {
args[j] = ((Double) value).floatValue();
} else if (value instanceof String) {
args[j] = Float.valueOf((String) value).floatValue();
} else {
throw new AppException(ajaxBean + "的参数和传入的参数类型不符。参数序号:" + ((Integer) j).toString() + ",参数类型:Float,传入类型:" + value.getClass());
}
} else if (parameter[j] == double.class || parameter[j] == Double.class) {
if (value instanceof Double) {
args[j] = value;
} else if (value instanceof Float) {
args[j] = ((Float) value).doubleValue();
} else if (value instanceof Integer) {
args[j] = ((Integer) value).doubleValue();
} else if (value instanceof String) {
args[j] = Double.valueOf((String) value).doubleValue();
} else {
throw new AppException(ajaxBean + "的参数和传入的参数类型不符。参数序号:" + ((Integer) j).toString() + ",参数类型:Double,传入类型:" + value.getClass());
}
} else if (parameter[j] == Date.class) {
if (value instanceof Date) {
args[j] = Date.valueOf(value.toString());
} else if (value instanceof String) {
args[j] = Date.valueOf(value.toString());
} else {
//返回错误,数据类型错误=========================================
throw new AppException(ajaxBean + "的参数和传入的参数类型不符。参数序号:" + ((Integer) j).toString() + ",参数类型:Date,传入类型:" + value.getClass());
}
}
}
}

dongchao_mygirl 2011-10-28
  • 打赏
  • 举报
回复
因为callObjectMethod方法最后一个参数是Object,int类型的会直接封装到Integer
1、楼主可以将原来的方法参数改为Integer
2、楼主可以再传递参数过程中进行一次判断:
if(args != null){
methodArgs = new Class[args.length];
for(Object obj:args){
if(obj instanceof Integer){
methodArgs[i] = int.class;
}else
methodArgs[i] = args[i].getClass();
}
}
这样的话,如果有其他基本类型的话,也需要进行判断

原因就是参数设定为Object后,基本类型的参数会进行自动封装

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧