我想写这么个函数:
参数:传进一个对象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);
}请问怎样实现??

解决方案 »

  1.   

    因为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后,基本类型的参数会进行自动封装
      

  2.   

    我的反射里是这样做的: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());
                }
            }
        }
    }
      

  3.   

    java基本数据类型对应的引用类型都有一个TYPE静态属性.
    例如Integer.TYPE是代表基本int数据类型
    例如有一个sub(int i)的方法,如果想反射调用Method method = class1.getMethod("sub",Integer.TYPE);
      

  4.   

    原来是没有把参数列表传进去。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