Java中使用列表的动态转换
我的API中的一个方法没有将Java.lang.Object类型作为参数,但它将它的所有子类型作为参数(Java.lang.Integer、Java.lang.String等) 现在,我想通过执行以下操作将数据类型存储在列表中:Java中使用列表的动态转换,java,list,casting,Java,List,Casting,我的API中的一个方法没有将Java.lang.Object类型作为参数,但它将它的所有子类型作为参数(Java.lang.Integer、Java.lang.String等) 现在,我想通过执行以下操作将数据类型存储在列表中: List<Object> listObjects = new ArrayList<Object>(); if(listObjects.get(0) instanceof Integer){ //then do listDataTypesForCa
List<Object> listObjects = new ArrayList<Object>();
if(listObjects.get(0) instanceof Integer){
//then do
listDataTypesForCast.add(Integer);
}
List listObjects=new ArrayList();
if(listObjects.get(0)instanceof Integer){
//那就做吧
listDataTypesForCast.add(整数);
}
所以,我可以这样投:
myMethod((listDataTypesForCast.get(0)“返回Java.lang.Object数据类型”))
但是,我不知道如何声明我的列表:listDataTypesForCast,以便我可以使用它进行强制转换。如果你知道答案,请告诉我
PS:我使用的是Apache POI库和setCellValue()方法,参数中不能有java.lang.Object作为数据类型,在单元格中插入值时我不能检查数据类型,因为它在循环中,会添加太多的锅炉板代码。如果要调用单个参数方法的多个重载之一,但是直到运行时才知道参数类型,您可以使用反射来完成 下面是一个帮助器方法:
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);
}
}
输出
String:Foo
电话:42
龙:42
数字:42.0
数字:42.0
然而,我的问题可以通过反射来解决(正如Andreas所建议的),但在这个特殊情况下,我决定不广泛使用反射,因为我有很多数据要写入excel单元格,因此,我使用了以下方法:
我相信instaceof也在内部使用反射,但我只需要使用一次。请至少尝试发布有效的Java代码<代码>新列表()将不会编译,因为
列表
是一个接口。--另外,为什么需要将类型存储在单独的列表中?对象已经知道它的类型。这是instanceof
检查它的方式。--不管怎么说,您所寻求的方法不会起作用,因为方法重载解析是在编译时完成的,而不是在运行时完成的。您所说的“…不将Java.lang.Object作为参数,但它将其所有子类型作为参数…”是什么意思?我认为在Java中不可能声明这样的参数。@DavidWallace我把它理解为方法重载,例如类有myMethod(Integer I)
,myMethod(String s)
,myMethod(Double d)
,…是的,我认为这可能是OP的意思,但在回答问题之前值得检查一下。如果它们真的是指“它的所有子类型”,那就太多了。@Andreas我很抱歉,写错了,现在更正了。你知道这方面的工作吗?我知道的解决方法太长了,因为它会为excel单元格中的每次插入包含太多if-elseif-instanceof语句。
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);
}