Java中使用列表的动态转换

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

我的API中的一个方法没有将Java.lang.Object类型作为参数,但它将它的所有子类型作为参数(Java.lang.Integer、Java.lang.String等)

现在,我想通过执行以下操作将数据类型存储在列表中:

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单元格,因此,我使用了以下方法:

  • 对于第一行单元格,使用instanceof找出每个数据(对象类型)的数据类型,然后将结果保存到Enum。因为其余的行在列之间共享相同的数据类型

  • 现在,循环遍历枚举并设置单元格值和数据类型


  • 我相信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);
    }