[英]Generics specifying both the interface and concrete class getting unchecked cast warning
[英]Unchecked Cast warning - shows up for Type parameters but not for Concrete types?
考虑以下片段:
Integer a = Integer.valueOf(23);
Double d = (Double) (Number) a; //not unchecked cast
List<String> stringList = new ArrayList<>();
List<Integer> integerList = (List<Integer>)(List<?>)stringList; //unchecked cast
Supertype -> Subtype
Unchecked cast 被标记为编译器直到运行时才知道Supertype
表示的类型是否与SubType
匹配。(Double) (Number)a
没有被标记为Unchecked Cast
?未经检查的强制转换被标记为编译器直到运行时才知道
Supertype
表示的类型是否与SubType
匹配。
那是不正确的。 甚至运行时都不知道您的列表是ArrayList<String>
还是ArrayList<Integer>
。 就运行时而言,您的列表是一个ArrayList
(这是因为类型擦除)。 这就是运行时无法检查将List<?>
转换为List<String>
的原因。 运行时不知道List<String>
是什么——它只知道List
。 对于运行时,不需要检查,因为您只是从List
到List
,这总是成功的。 事实上,在运行时没有为这个强制转换做任何事情——它是一个完全未经检查的强制转换。
因此,此代码运行时不会引发异常:
List<String> stringList = new ArrayList<>();
stringList.add("foo");
List<Integer> integerList = (List<Integer>)(List<?>)stringList;
System.out.println(integerList.size());
但是,如果您这样做,它将引发异常:
List<String> stringList = new ArrayList<>();
stringList.add("foo");
List<Integer> integerList = (List<Integer>)(List<?>)stringList;
System.out.println(integerList.get(0) - 1);
现在,您正在从列表中获取一个整数,并对它执行一些特定于整数的操作。 但是列表包含"foo"
,它不是整数。 编译器插入一个隐式转换来将integerList.get(0)
为Integer
,并且转换失败。 请注意,这是一个已检查的强制转换,因为运行时知道Integer
类型。
还会检查从Number
到Double
,因为运行时知道Double
。
旁注:还有“部分未经检查的强制转换”,例如从Object
强制转换为ArrayList<String>
。 运行时可以检查Object
是否为ArrayList
,但无法检查它是否为字符串数组列表。
在此处查看已检查和未检查的所有规则。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.