因此,在使用具有 List(或 Map 或 Set 等)作为属性的泛型类时,我遇到了一个奇怪的编译错误。
尝试迭代(使用 foreach)列表时出现编译错误:
Sample.java:11: error: incompatible types
for (String string : s.getStringList()) {
required: String
found: Object
明确一点,我知道这个问题有一个简单的解决方法,但我想了解代码有什么问题
以下是我创建的示例:
import java.util.List;
public class Sample<T> {
public List<String> stringList;
public static void main(String[] args) {
Sample s = new Sample();
// Why this doesn't work?
for (String string : s.getStringList()) {
}
// Why does both of the following work?
List<String> newList = s.getStringList();
Sample<Object> s2 = new Sample<>();
for (String string : s2.getStringList()) {
}
}
public List<String> getStringList() {
return stringList;
}
}
最佳答案
这些行
Sample s = new Sample();
// Why this doesn't work?
for (String string : s.getStringList()) {
}
不起作用,因为您使用的是 Sample
的原始 形式类(class)。当您使用类的原始形式时,类中的所有 泛型,甚至不相关的泛型,都会执行类型删除。这意味着 getStringList
现在只返回 List
的 Object
s,不是 List<String>
的 String
这部分 Java 是在 Java 1.5 中随泛型一起引入的,这样现在使用泛型的旧版本类就可以向后兼容。这样,迭代 List
的东西,必须使用 Object
之前,还能用Object
通过使用 List
的原始形式.
JLS, Section 4.8处理原始类型:
More precisely, a raw type is defined to be one of:
- The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.
和
The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.
(强调我的)
推理:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.
关于java - 泛型类和列表的奇怪编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22392379/