为什么编译器只给出一个警告(“ArrayList
是一个原始类型,引用通用类型ArrayList<E>
应该参数化”)并编译代码?为什么它不会在运行时给出错误,编译器将无法将我们的数据类型转换为指定的参数类型?为什么编译器允许引用未被参数化的泛型类型?
回答
考虑一个例子时的ArrayList不参数
ArrayList listOfObjects = new ArrayList();
listOfObjects.add("someStringValue");
listOfObjects.add(new Integer(10));
listOfObjects.add(new Dog());
一切都有了有效的,所以你可以在listOfObjects添加任何东西。
但如果你将其参数化,
ArrayList<String> listOfStrings = new ArrayList<String>();
listOfStrings.add("someStringValue");
listOfStrings.add(new Dog()); // Boom, compiler error, can't add dogs into list of strings
编译是成功的,因为一般的代码需要在其仿制药未使用的遗留代码兼容。
也有在运行时没有类型安全,
OP已经知道这一点。 OP的问题是为什么编译器允许将原始类型引用赋值给参数化类型。 @Joachim正确回答了下面的问题。 – Santosh
我也用粗体回答了OP的问题。 –
引用泛型类型不带参数被称为raw types。
编译器允许其使用的唯一原因是向后兼容性:每一代Java编译器都试图尽可能向后兼容旧代码。由于在Java 5中引入的泛型,许多旧代码根本没有使用它们。
从JLS甲报价(如上面链接):
使用原始类型被允许仅作为让步的遗留代码兼容。强烈建议在将泛型引入Java编程语言之后编写的代码中使用原始类型。未来版本的Java编程语言可能会禁止使用原始类型。
由于太阳不希望引入一个平行宇宙ArrayList
和相关的类,它决定添加泛型类型信息的集合(和许多其他地方),并定义了JLS的方式,允许老,非 - 通用代码仍然需要编译(但有警告)。
在编写良好的新代码中,不会与旧的和/或破坏的库原始类型进行交互,这绝不是必需的。
Java中引入了泛型以提供集合的一致性。
即,如果您将集合传递给没有泛型的方法,那么该方法将不知道从集合中检索元素时会发生什么。
例如如果你传递一个包含所有没有泛型的字符串的集合,那么该方法可能会插入一个不正确的对象。
泛型只有在编译时才可用。编译后,“type erasure
”发生,编译器将消除所有泛型。
类型擦除在this link解释。
- 1. 为什么这种类型不允许使用类型参数?
- 2. 泛型方法与类型参数不被Java编译器
- 3. 为什么泛型参数“扩展”派生函数中不允许的东西,但泛型返回类型是?
- 4. 为什么编译器不能推断泛型类型
- 5. 作为泛型参数传递时,为什么泛型类型不被识别为其派生类型?
- 6. Swift泛型 - 允许作为参数传递的子类
- 7. Scala编译器推断泛型参数
- 8. 为什么编译器会为我的泛型函数参数抱怨“不兼容的类型”?
- 9. 在C#泛型泛型类型参数,允许以某种形式
- 10. Java - 本地类和泛型,为什么编译器警告?
- 11. 为什么泛型在“?extends Klass”被允许时被认为是不变的?
- 12. 为什么Java不允许基于类型参数的重载?
- 13. 为什么模板允许未完成类的方法类型?
- 14. Java的泛型参数化类型
- 15. 泛型类型的参数化方法
- 16. 为什么忽略参数类型时泛型完全禁用?
- 17. 为什么一个接口参数允许任何类型
- 18. MonoTouch AOT编译器未构造泛型中的字典类型
- 19. 为什么socketpair()允许SOCK_DGRAM类型?
- 20. 为什么通用类型参数的类允许在类内抛出
- 21. 如何限制在泛型类中允许为“T”的类型?
- 22. 为什么明确地专门化泛型函数是不允许的?
- 23. 泛型类型作为泛型类型参数
- 24. C#将泛型类型作为泛型类型参数传递?
- 25. 为什么我需要在泛型类中明确定义泛型参数的泛型类型?
- 26. Rust编译器为什么要求我限制泛型类型参数的生存期(错误E0309)?
- 27. 允许列表中的所有类型的泛型类型
- 28. 为什么Scala编译器禁止将通配符类型声明为类型参数的超类型
- 29. 为什么std :: future模板参数类型是引用类型?
- 30. 为什么不允许使用泛型和通配符?
因为类型是在运行时反正擦除。 –
结合Oli的评论,编译器将用户Object作为类型。 – Leon