如何通过 "Double" 对象获得 "double.class"

How to get "double.class" by a "Double" Object

描述:

代码:

test.java
    public static void main( String args[] )
    {
        Object obj = new Foo();
        Object s = 1.2;
        String type = "Double";
        try {
            Method method = obj.getClass().getMethod("return" + type, s.getClass());// got NoSuchMethodException here, because it requires `double` not Double
            System.out.println(method.invoke(obj,s));
        } catch (NoSuchMethodException | IllegalAccessException |InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
Foo.java //(I can't change/add code/delete in this part)
public class Foo {
    public double returnDouble(double type){
        return type;
    }
    public int returnInt(int type){
        return type;
    }
}

我尝试过的:

    public static void main( String args[] )
    {
        Object obj = new Foo();
//        Object s = 1;
//        String type = "Int";
        Object s = 1.2;
        String type = "Double";
        Map<String, Class> methodClassMap = new HashMap<String, Class>() {{
            put("Double",double.class);
            put("Integer",int.class);
        }};
        try {
            Method method = obj.getClass().getMethod("return" + type, methodClassMap.get(s.getClass().getSimpleName()));
            System.out.println(method.invoke(obj,s));
        } catch (NoSuchMethodException | IllegalAccessException |InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

问题:

如果事先知道目标方法总是使用原始类型,则可以使用 java.lang.invoke 包的 MethodTypeunwrap() 方法。

Object obj = new Foo();
Object s = 1.2;
String type = "Double";
try {
    MethodType mt = MethodType.methodType(s.getClass(), s.getClass()).unwrap();
    Method method = obj.getClass().getMethod("return" + type, mt.parameterArray());
    System.out.println(method.invoke(obj, s));
} catch(ReflectiveOperationException e) {
    e.printStackTrace();
}

或者,当您已经在使用 java.lang.invoke 包的方法类型时,您也可以使用方法句柄来执行调用。

Object obj = new Foo();
Object s = 1.2;
String type = "Double";
try {
    MethodType mt = MethodType.methodType(s.getClass(), s.getClass()).unwrap();
    MethodHandle mh = MethodHandles.lookup().bind(obj, "return" + type, mt);
    System.out.println(mh.invoke(s));
} catch(Throwable e) {
    e.printStackTrace();
}

但请注意,与反射不同,必须为查找正确指定 return 类型。我假设 return 类型与参数类型相同,就像您的示例一样。