如何通过“双”对象获取“double.class”

lea*_*ori 4 java reflection

描述:

  • 我需要使用getMethod,它需要参数类型。
  • origin 方法需要double(原始类型,而不是Double),并且我无法更改 origin 方法。
  • 我不能只输入double.class参数s类型,因为可能不同的类型,例如Integer(not int)。
  • 中的方法参数Foo.java始终且仅是原始类型。

代码:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过的:

  • 使用地图
    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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 它有效,但我必须列出所有可能的值类型s

题:

  • 有比使用 Map 更好的解决方案吗?也许使用泛型?

Hol*_*ger 5

当你事先知道目标方法总是用一种原始的类型,可以使用unwrap()的方法MethodType中的java.lang.invoke包。

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();
}
Run Code Online (Sandbox Code Playgroud)

或者,当您已经在使用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();
}
Run Code Online (Sandbox Code Playgroud)

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