Java 重新创建方法调用(使用反射)

Java 重新创建方法调用(使用反射),java,reflection,Java,Reflection,如何重新创建方法调用?当我得到的只是通过getDeclaredMethods()获得的方法列表,并转换为HashMap及其参数类列表,通过getParameterTypes()获得 假设我从用户处获得一个字符串,并希望调用它: "print(3,"Hello World!",true,2.4f)" 方法print(int,String,boolean,float)是getMethods()数组的一部分。我很难弄清楚如何编写调用。到目前为止,我得到的是: private static final

如何重新创建方法调用?当我得到的只是通过
getDeclaredMethods()
获得的方法列表,并转换为
HashMap
及其参数类列表,通过
getParameterTypes()
获得

假设我从用户处获得一个字符串,并希望调用它:

"print(3,"Hello World!",true,2.4f)"
方法
print(int,String,boolean,float)
是getMethods()数组的一部分。我很难弄清楚如何编写调用。到目前为止,我得到的是:

private static final Pattern functionCall = Pattern.compile(String.format("^%s\\(%s?\\)$", "(\\w+)", "(.*)"));

if( (m = functionCall.matcher(line)).find() ) {
    String function = m.group(1); // in this example = "print"
    String arguments = m.group(2); // in this example = "3,\\"Hello World!\\",true,2.4f"
    if( methods.containsKey(function) ) {
        Method method = methods.get(function);
        Class<?>[] paramsExpected = method.getParameterTypes();
        String [] paramsActual = arguments.split(",");
        if( paramsExpected.length != paramsActual.length ) {
            throw new IllegalArgumentException(function + ": bad number of arguments");
        }
        for( Class<?> param: paramsExpected) {
            ???????
        }
        method.invoke(context, ??????);
private static final Pattern functionCall=Pattern.compile(String.format(“^%s\\(%s?\\)$”、“(\\w+”、“(.*)”);
if((m=functionCall.matcher(line)).find()){
String function=m.group(1);//在本例中为=“打印”
String arguments=m.group(2);//在本例中=“3,\\\“Hello World!\\”,true,2.4f”
if(methods.containsKey(函数)){
Method=methods.get(函数);
类[]paramsExpected=method.getParameterTypes();
字符串[]paramsActual=arguments.split(“,”);
if(paramsExpected.length!=paramsActual.length){
抛出新的IllegalArgumentException(函数+“:参数数错误”);
}
for(类参数:paramsExpected){
???????
}
方法。调用(上下文,??);

非常清楚地说,我事先不知道用户将输入什么字符串,我必须对照可用的方法及其参数进行检查,如果我找到了它,那么我必须使用用户提供的参数调用它。

这就是您需要做的。一个选项是使用BeanUtils方法将字符串转换为特定类型。这将适用于内置类型

    Object[] args = new Object[paramsExpected.length];
    int i = 0;  
    for( Class<?> param: paramsExpected) {
        args[i] = convertStringToType(paramsActual[i], param);
        i  = i +1;
    }
    method.invoke(context, args);

    Object convertStringToType(String input, Class<?> type) {
      return ConverterUtils.convert(input,type);
    }
Object[]args=新对象[paramsExpected.length];
int i=0;
for(类参数:paramsExpected){
args[i]=convertStringToType(paramsActual[i],param);
i=i+1;
}
调用(上下文,参数);
对象convertStringToType(字符串输入,类类型){
返回ConverterUtils.convert(输入,类型);
}

这无疑是向前迈出的一步。我查看了您提供的链接,不清楚它如何处理int、boolean等基本体。它似乎只转换对象。
convert(类类型、对象值)将指定的输入对象转换为指定类型的输出对象。
(当然你忘了增加
i
,但那是次要的)反射api不区分原语和对象包装器。即使原语也会转换为其等效的包装器类型。您可以通过打印每个参数的类名来验证这一点。我想我会自己使用
param.getSimpleName()将您的答案部分转换为参数
参数getCanonicalName()
然后应用适当的
valueOf()