我的API中的一个方法,不将Java.lang.Object类型作为参数,但它将所有子类型作为参数(java.lang.Integer,java.lang.String)等)。
现在,我想通过执行以下操作将DataType存储在列表中:
List<Object> listObjects = new ArrayList<Object>();
if(listObjects.get(0) instanceof Integer){
//then do
listDataTypesForCast.add(Integer);
}
所以,我可以这样投:
myMethod((listDataTypesForCast.get(0)&#34;返回Java.lang.Object数据类型&#34;))
但是,我不知道如何声明我的 List:listDataTypesForCast ,以便我可以将它用于Casting。如果你知道答案,请告诉我?
PS:我使用Apache POI库和setCellValue()方法,不能将java.lang.Object作为参数中的DataType,我当时无法检查DataType在单元格中插入值,因为它在一个循环中,它将添加太多的锅炉板代码。
答案 0 :(得分:1)
如果要调用单参数方法的多个重载之一,但在运行时之前不知道参数类型,则可以使用反射来完成。
这是一个帮助方法:
private static void call(Object obj, String methodName, Object arg) {
Class<?> argClass = arg.getClass();
// Try simple approach
Method methodToCall;
try {
methodToCall = obj.getClass().getMethod(methodName, argClass);
} catch (@SuppressWarnings("unused") NoSuchMethodException unused) {
methodToCall = null;
}
// Search for method, if simple approach didn't work
if (methodToCall == null) {
List<Method> candidates = new ArrayList<>();
for (Method method : obj.getClass().getMethods()) { // Note: Public methods only
if (method.getParameterCount() == 1 && method.getName().equals(methodName)) {
Parameter parameter = method.getParameters()[0];
if (parameter.getType().isAssignableFrom(argClass))
candidates.add(method);
}
}
if (candidates.isEmpty()) {
throw new NoSuchMethodError(obj.getClass().getName() + '.' +
methodName + '(' + argClass.getName() + ')');
}
if (candidates.size() > 1) {
// Implement extended overload resolution logic, if needed
throw new NoSuchMethodError("Multiple candidates found for parameter type " +
argClass.getName() + ": " + candidates);
}
methodToCall = candidates.get(0);
}
// Call method
try {
methodToCall.invoke(obj, arg);
} catch (IllegalAccessException e) {
throw new IllegalAccessError(e.getMessage());
} catch (InvocationTargetException e) {
throw new RuntimeException("Checked exception: " + e.getCause(), e);
}
}
测试
public static void main(String[] args) {
Test obj = new Test();
for (Object arg : Arrays.asList("Foo", 42, 42L, 42f, 42d))
call(obj, "myMethod", arg);
}
public void myMethod(String s) {
System.out.println("String: " + s);
}
public void myMethod(Number s) {
System.out.println("Number: " + s);
}
public void myMethod(Long s) {
System.out.println("Long: " + s);
}
输出
String: Foo
Number: 42
Long: 42
Number: 42.0
Number: 42.0
答案 1 :(得分:0)
然而,我的问题可以使用Reflection解决(正如Andreas所建议的那样)但是,在这种特殊情况下,我决定不广泛使用反射,因为我有很多数据要写入excel单元格,因此,我使用了以下方法:
使用instanceof查找每个数据(类型为Object)的数据类型,对于第一行单元格,然后将结果保存到Enum。因为其余行在列之间共享相同的数据类型。
现在,循环遍历枚举并设置单元格值和数据类型。
我相信instaceof也在内部使用反射,但我只需要使用一次。