无法推断泛型类型“?super SomeClass”

时间:2015-10-21 11:54:55

标签: java generics type-inference

在尝试使用我的通用方法识别问题之后,我最终得到了以下代码:

        Map<String, BiConsumerThatThrows<CheckPayment, XMLEventReader>> a = CheckPayment.childMapper;
        BiConsumerThatThrows<CheckPayment, XMLEventReader> a1 = a.get("1");
        BiConsumerThatThrows<? super CheckPayment, XMLEventReader> b1 = a1;
        Map<String, BiConsumerThatThrows<? super CheckPayment, XMLEventReader>> b = new HashMap<>();
        b.put("1", b1);
        b = a;

它不会编译时出现以下错误(我将其格式化以使其更具可读性):

[ERROR] /D:/lalala/MyClass.java:[152,27] 
    incompatible types: 
        java.util.Map<
            java.lang.String,
            blablabla.BiConsumerThatThrows<
                blablabla.CheckPayment,
                javax.xml.stream.XMLEventReader
            >
        > 
    cannot be converted to 
        java.util.Map<
            java.lang.String,
            blablabla.BiConsumerThatThrows<
                ? super blablabla.CheckPayment,
                javax.xml.stream.XMLEventReader
            >
        >

最令人惊讶的是,它只在给定代码段的最后一行崩溃。

为什么会这样?如何执行此类任务?

我正在使用Oracle JDK 1.8u40 x64。

P.S。这是简化的例子:

Set<Set<String>> sets = new HashSet<>();
Set<Set<? super String>> sets2 = new HashSet<>();
sets2 = sets;

错误:

incompatible types: java.util.Set<java.util.Set<java.lang.String>> cannot be converted to java.util.Set<java.util.Set<? super java.lang.String>>

P.P.S。即使这样也行不通:

Set<Set<Object>> sets2 = new HashSet<Set<String>>();

为什么?

1 个答案:

答案 0 :(得分:3)

问题是泛型类型参数约束对嵌套约束不透明。 Map<String, List<Integer>>Map<String, List<? super Integer>>的类型不同,您无法将其中一个分配给另一个。这是你在这里遇到的问题。

要修复它,您需要使用extends将通配符一直应用到顶级泛型声明:

Map<String, ? extends List<? super Integer>> m = new HashMap<String, List<Integer>>()

请注意,这是extends,而不是super,因为List<Integer>List<? super Integer> sub 类型(我发现这个心灵弯曲)。所以在你的情况下,这将是:

Map<String, ? extends BiConsumerThatThrows<? super CheckPayment, XMLEventReader>> b = ...

和简化示例:

Set<? extends Set<? super String>> sets2 = new HashSet<>();

这有助于理解这一点:http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#FAQ104