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

Java整数到字符串的转换不一致,java,arrays,Java,Arrays,为什么从整数集合到字符串集合的转换是有效的,但当我实际上必须将整数转换为字符串时,转换失败了? 为什么它会失败/更早地抓住它? 在我下面的例子中 static <T extends List<?> > void testConversion(T... args) { **// Didnt catch here?** List<String>[] slarray = (List<String>[])ar

为什么从整数集合到字符串集合的转换是有效的,但当我实际上必须将整数转换为字符串时,转换失败了? 为什么它会失败/更早地抓住它? 在我下面的例子中

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));
    }

static这是因为Java泛型是编译时的东西,而实际类型在程序运行时被删除

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

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


但是,在获取实际值时,运行时环境可以看到该值实际上无法分配给字符串,因此它会抛出一个异常。

这是因为Java泛型是编译时的东西,而实际类型在程序运行时会被删除

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

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


但是,在获取实际值时,运行时环境可以看到该值实际上无法分配给字符串,因此它会抛出一个异常。

这是因为Java泛型是编译时的东西,而实际类型在程序运行时会被删除

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

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


但是,在获取实际值时,运行时环境可以看到该值实际上无法分配给字符串,因此它会抛出一个异常。

这是因为Java泛型是编译时的东西,而实际类型在程序运行时会被删除

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

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


但是,在获取实际值时,运行时环境会发现该值实际上无法分配给字符串,因此会引发异常。

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

您告诉编译器,
args
,它知道是
T[]
,可以强制转换为
列表[]
。您还告诉编译器,
args[0]
(它接受为
T
)是一个
列表

在这里,当调用
testConversion
时,您正在传递
List
s。类型
T
被推断为
Integer
。然而,由于类型擦除,在运行时,它们实际上是
List
s。此外,对
List[]
List
的转换也会成功,因为在运行时,它们实际上分别被转换为
List[]
List

编译时,您应该收到一条未选中的强制转换警告,提示您如何强制转换到
List[]
List
。它是在警告你类型安全。它还在调用
get
时插入了对
String
的强制转换,因为您告诉它这是一个
列表
。当您最终尝试从
列表中获取
字符串时,JVM抛出了一个运行时异常,因为该元素实际上是一个
整数


当您将
args
强制转换为
List[]
时,当您将
args[0]
强制转换为
List
时,您向编译器撒谎,但JVM发现了您的谎言。

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

您告诉编译器,
args
,它知道是
T[]
,可以强制转换为
列表[]
。您还告诉编译器,
args[0]
(它接受为
T
)是一个
列表

在这里,当调用
testConversion
时,您正在传递
List
s。类型
T
被推断为
Integer
。然而,由于类型擦除,在运行时,它们实际上是
List
s。肌萎缩侧索硬化