如何通过 "Double" 对象获得 "double.class"
How to get "double.class" by a "Double" Object
描述:
- 我需要使用
getMethod
,它需要parameterTypes.
- origin 方法需要
double
(基本类型,而不是 Double
),我不能更改 origin 方法。
- 我不能只在参数类型中输入
double.class
,因为s
可能是不同的类型,例如Integer
(不是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;
}
}
我尝试过的:
- 使用地图
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();
}
}
}
- 有效,但我必须列出所有可能的值类型
s
。
问题:
- 有比使用 Map 更好的解决方案吗?也许使用通用?
如果事先知道目标方法总是使用原始类型,则可以使用 java.lang.invoke
包的 MethodType
的 unwrap()
方法。
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 类型与参数类型相同,就像您的示例一样。
描述:
- 我需要使用
getMethod
,它需要parameterTypes. - origin 方法需要
double
(基本类型,而不是Double
),我不能更改 origin 方法。 - 我不能只在参数类型中输入
double.class
,因为s
可能是不同的类型,例如Integer
(不是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;
}
}
我尝试过的:
- 使用地图
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();
}
}
}
- 有效,但我必须列出所有可能的值类型
s
。
问题:
- 有比使用 Map 更好的解决方案吗?也许使用通用?
如果事先知道目标方法总是使用原始类型,则可以使用 java.lang.invoke
包的 MethodType
的 unwrap()
方法。
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 类型与参数类型相同,就像您的示例一样。