字符串被分配给一个没有编译错误的列表
String gets assigned to a List without a compilation error
据我所知,Java 中泛型的主要目的之一是提供编译时类型安全。如果它被编译,代码将 运行 没有问题。
那为什么会编译下面的代码呢?
public static void main(String[] args) {
String s = getList();
}
private static <T extends List> T getList() {
return (T)new ArrayList();
}
编译正常。我的类型安全编译在哪里? getList()
方法与 String
class.
没有任何共同之处
这本身不是类型擦除问题,而是几乎相反:您在运行时遇到问题,系统知道实际类型,但在编译时不知道。编译的原因是 List
是一个接口。就编译器而言,String
的子 class 可能实际上实现了该接口,因此编译器认为可能存在有效的运行时情况,其中返回的实际对象是 String
那也是一个List
。编译器不认为 String 是最终的,因此不可能实际创建 List
-实现 String
class.
至于为什么编译时不考虑final,Bohemian对该问题的评论给出了很好的解释。
据我所知,Java 中泛型的主要目的之一是提供编译时类型安全。如果它被编译,代码将 运行 没有问题。
那为什么会编译下面的代码呢?
public static void main(String[] args) {
String s = getList();
}
private static <T extends List> T getList() {
return (T)new ArrayList();
}
编译正常。我的类型安全编译在哪里? getList()
方法与 String
class.
这本身不是类型擦除问题,而是几乎相反:您在运行时遇到问题,系统知道实际类型,但在编译时不知道。编译的原因是 List
是一个接口。就编译器而言,String
的子 class 可能实际上实现了该接口,因此编译器认为可能存在有效的运行时情况,其中返回的实际对象是 String
那也是一个List
。编译器不认为 String 是最终的,因此不可能实际创建 List
-实现 String
class.
至于为什么编译时不考虑final,Bohemian对该问题的评论给出了很好的解释。