变量类型(通用或非通用)更改属性行为

时间:2019-05-17 16:37:48

标签: java generics

最少繁殖:

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泛型,我可能会误解一些,但是呢?

谢谢

1 个答案:

答案 0 :(得分:3)

最后一行不会编译,但这不是因为您使用Irrelevant类,而是因为变量t3是原始的。

使用原始类型时,该类中的所有泛型,甚至是无关的泛型(例如testMap变量的类型参数)也会进行类型擦除,就好像它们也是原始的一样。这是由于从JDK 1.5中将泛型引入Java以来​​的向后兼容规则。

有效地,这意味着testMap现在只是原始Map,其Iterator返回Object。这会导致您看到的编译错误。您可以为t3变量提供type参数,编译错误将被消除。

TestGeneric<Irrelevant> t3 = new TestGeneric<>();