Java转换整数到字符串不一致

时间:2015-03-02 20:01:37

标签: java arrays

为什么从Integers集合到String集合的转换工作但是当我实际上必须将Integer转换为String时它会失败? 为什么它会失败/赶上它? 在我的下面的例子中

static <T extends List<?> >
    void testConversion(T... args)
    {
        **// Didnt catch here?**
        List<String>[] slarray = (List<String>[])args;
        System.out.printf("Value is %s\n", slarray[0].get(0));
        **// Didnt catch here?**
        List<String> slist = (List<String>)args[0];
        // FAIL runtime exception
        String s2 = slist.get(0);
        // FAIL exception
        String s = slarray[0].get(0); 
    }

public static void main( String[] args )
    {
        testConversion(Arrays.asList(11,12), Arrays.asList(21,22));
    }

2 个答案:

答案 0 :(得分:2)

这是因为Java Generics是编译时的事情,并且在程序运行时会删除实际类型。

您将T定义为“任何内容列表”。然后,将对“List of whatever”的引用转换为“String of List”。这种类型转换可能有效(因此,它不是编译时错误),因此编译器不会抱怨,而是将问题留给运行时系统。

在运行时,它只是对List的引用。因此,运行时环境也不会抱怨 - 您投射了一个List数组并将其分配给List数组,此时实际类型将被删除。

但是在获取实际值时,运行时环境可以看到该值实际上不能分配给String,因此它会引发异常。

答案 1 :(得分:1)

当您在代码中提供强制转换时,您告诉编译器,“我知道您有一个 x 的实例,但我知道它实际上是 y 。将其视为 y 。“如果完全可以进行强制转换,那么编译器将允许它。

您告诉编译器args,它知道是T[],可以转换为List<String>[]。您还告诉编译器args[0],它接受​​的是T,是List<String>

这里发生的是,在调用testConversion时,您正在传递List<Integer>。类型T被推断为Integer。但是,由于类型擦除,在运行时,它们实际上是List s。此外,对List<String>[]List<String>的强制转换成功,因为在运行时,它们实际上分别转换为List[]List

编译时,您应该收到一封关于投放到List<String>[]List<String>的未经检查的投射警告。它警告你关于类型安全。它还会在String的调用中向get插入强制转换,因为您告诉它它是List<String>。当您最终尝试从String获得List<String>时,JVM会抛出运行时异常,因为该元素确实是Integer

当您将args投放到List<String>[]时,以及当您将args[0]投放到List<String>时,您会欺骗编译器,但JVM会抓住您的谎言。< / p>