字符串被分配给一个没有编译错误的列表 [英] String gets assigned to a List without a compilation error
问题描述
据我所知,Java 中泛型的主要目的之一是提供编译时类型安全.如果它被编译,代码将毫无问题地运行.
As I know, one of the main purposes of generics in Java is providing compile-time type safety. If it gets compiled, the code will run without issues.
那为什么下面的代码会被编译?
Then why is the following code being compiled?
public static void main(String[] args) {
String s = getList();
}
private static <T extends List> T getList() {
return (T)new ArrayList();
}
它编译得很好.我的类型安全编译在哪里?getList()
方法与 String
类没有任何共同之处.
It compiles fine. Where is my type-safe compilation? The getList()
method has nothing in common with the String
class.
推荐答案
这本身不是类型擦除问题,而是几乎相反:您在运行时遇到问题,当系统知道实际类型,但在编译时间.这个编译的原因是 List
是一个接口.就编译器而言,String
的子类可能实际上实现了该接口,因此编译器认为可能存在有效的运行时情况,其中返回的实际对象是 String
> 那也是一个 List
.编译器不认为 String 是最终的,因此实际上不可能创建一个 List
实现 String
类.
This is not a type erasure problem per se, but almost the opposite: You get a problem at runtime, when the system knows the actual types, but not at compile time. The reason why this compiles is that List
is an interface. As far as the compiler is concerned, a subclass of String
might actually implement that interface, so the compiler reasons that there could be valid runtime situations where the actual object returned is a String
that is also a List
. The compiler does not consider that String is final, and thus that it's impossible to actually create a List
-implementing String
class.
至于为什么编译时不考虑final,Bohemian对问题的评论给出了很好的解释.
As to why final is not considered during compilation, Bohemian's comment to the question gives a good explanation.
这篇关于字符串被分配给一个没有编译错误的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!