最少繁殖:
public class Main {
public static class TestGeneric<T> {
Map<String, Integer> testMap = new HashMap<>();
}
public static class Test {
Map<String, Integer> testMap = new HashMap<>();
}
public static class Irrelevant {}
public static void main(String[] args) {
// Not generic, no problem.
Test t = new Test();
Map.Entry<String, Integer> entry = t.testMap.entrySet().iterator().next();
// Generic, but variable type also include generic information.
TestGeneric<Irrelevant> t2 = new TestGeneric<>();
Map.Entry<String, Integer> entry2 = t2.testMap.entrySet().iterator().next();
// Generic, but variable type doesnt keep this info.
TestGeneric t3 = new TestGeneric<Irrelevant>();
Map.Entry<String, Integer> entry3 = t3.testMap.entrySet().iterator().next();
}
}
由于Object cannot be converted to Entry<String, Integer>
,最后一行无法编译。
唯一的区别似乎是“根”变量的类型。 t3
的类型为TestGeneric
,而t2
的类型为TestGeneric<Irrelevant>
。
我不明白变量的类型如何改变类型不变的类属性的返回类型。在所有情况下,testMap
仍然是Map<String, Integer>
,但其entrySet()
会更改返回类型。
关于Java泛型,我可能会误解一些,但是呢?
谢谢
答案 0 :(得分:3)
最后一行不会编译,但这不是因为您使用Irrelevant
类,而是因为变量t3
是原始的。
使用原始类型时,该类中的所有泛型,甚至是无关的泛型(例如testMap
变量的类型参数)也会进行类型擦除,就好像它们也是原始的一样。这是由于从JDK 1.5中将泛型引入Java以来的向后兼容规则。
有效地,这意味着testMap
现在只是原始Map
,其Iterator
返回Object
。这会导致您看到的编译错误。您可以为t3
变量提供type参数,编译错误将被消除。
TestGeneric<Irrelevant> t3 = new TestGeneric<>();