[英]Java conversion Integer to String inconsistency
Why does conversion from collection of Integers to collection of String work but it fails when I actually has to convert the Integer to String? 为什么从整数的集合转换为String的集合有效,但是当我实际上必须将Integer转换为String时却失败了? Why dosent it fail/catch it earlier?
为什么要使它失败/更早捕获? In my example below
在下面的示例中
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));
}
This is because Java Generics are a compile time thing, and the actual type is erased when the program runs. 这是因为Java泛型是编译时的东西,程序运行时会删除实际类型。
You defined your T
as a "List of whatever". 您将
T
定义为“任何清单”。 You then cast a reference to a "List of whatever" to a "List of String". 然后,将对“任何列表”的引用转换为“字符串列表”。 It may be possible that this type cast will work (thus, it is not a compile-time error), and so the compiler doesn't complain, but leaves the issue to the run-time system.
这种类型转换可能会起作用(因此,这不是编译时错误),因此编译器不会抱怨,而是将问题留给了运行时系统。
In run time, it's just a reference to a List
. 在运行时,它只是对
List
的引用。 So the run time environment doesn't complain either - you cast an array of List
and assign it to an array of List
, and the actual type is erased at this point. 因此,运行时环境也不会抱怨-您投射了一个
List
数组并将其分配给List
数组,此时实际类型已被擦除。
But when it comes to getting the actual values, the run time environment can see that the value cannot actually be assigned to a String, and so it throws an exception. 但是当涉及到获取实际值时,运行时环境可以看到该值实际上无法分配给String,因此它引发了异常。
When you provide a cast in your code, you are telling the compiler, "I know you have an instance of x , but I know it's really a y . Treat it as a y ." 当您在代码中提供强制转换时,您会告诉编译器:“我知道您有x的实例,但我知道它确实是y 。请将其视为y 。” If the cast is possible at all, then the compiler will allow it.
如果完全可以进行强制转换,则编译器将允许它。
You are telling the compiler that args
, which it knows is a T[]
, can be cast to a List<String>[]
. 您正在告诉编译器可以将
args
(它知道是T[]
强制转换为List<String>[]
。 You are also telling the compiler that args[0]
, which it accepts to be a T
, is a List<String>
. 您还告诉编译器
args[0]
(它接受为T
)是List<String>
。
It happens here that when calling testConversion
, you are passing List<Integer>
s. 发生这种情况是,在调用
testConversion
,您正在传递List<Integer>
。 The type T
is inferred to be Integer
. 类型
T
推断为Integer
。 However, because of type erasure, at runtime, they are really List
s. 但是,由于类型擦除,在运行时它们实际上是
List
。 Also, the cast to List<String>[]
and List<String>
succeed, because at runtime, they are really casts to List[]
and List
, respectively. 另外,对
List<String>[]
和List<String>
成功,因为在运行时,它们实际上分别对List[]
和List
转换。
When you compiled, you should have received an unchecked cast warning about casting to List<String>[]
and to List<String>
. 编译时,应该收到未经检查的有关转换为
List<String>[]
和List<String>
强制转换警告。 It was warning you about type safety. 它警告您有关类型安全。 It also inserted a cast to
String
on the call to get
, because you told it that it was a List<String>
. 它还在
get
的调用上插入了对String
的强制转换,因为您告诉它它是List<String>
。 When you finally attempted to get a String
out your List<String>
, the JVM threw a runtime exception because the element really was an Integer
. 当您最终尝试从
List<String>
获取String
时,JVM抛出了运行时异常,因为该元素确实是Integer
。
When you casted args
to a List<String>[]
, and when you casted args[0]
to a List<String>
, you lied to the compiler, but the JVM caught your lie. 将
args
转换为List<String>[]
,以及将args[0]
强制转换为List<String>
,您都对编译器撒谎,但是JVM欺骗了您。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.