当上限通配符与较低的通配符一起使用时,编译失败

时间:2017-07-14 23:53:41

标签: java generics javac pecs

情况:我正在创建一个配置库,其中包含一个表示数据的Config接口,以及一个像这样的Parser接口:

public interface Parser<C extends D, D extends Config> {
    C parse(File f);
    void parse(File f, D destination);
}

解析器必须能够将数据解析为新的Config对象(C)或现有的(D)。 C扩展了D,因为我们可以手动创建C并将数据解析到它中是合乎逻辑的。当然,D扩展了Config,因为我们解析了配置。

假设我们有一个实现Config的MyConfig类(但它也可以是通用的“T extends Config”),我们想要一个可以创建和解析它的Parser。让我们遵循PECS规则:

  • 我们的解析器可以解析MyConfig,但也许它的超类型=&gt;我应该使用“?super MyConfig”
  • 我们的解析器可以生成MyConfig,但实际上它可能会产生一个 subtype =&gt;我应该使用“?extends MyConfig”

因此我最终得到了这个:

Parser<? extends MyConfig, ? super MyConfig> parser;

但是虽然IntelliJ没有抱怨什么,但编译(javac 1.8.0_131)失败并出现此错误:

  

类型参数?扩展package.MyConfig不在类型变量C

的范围内

这很奇怪,因为“MyConfig的某些子类型”显然是“MyConfig的某些超类型”的子类型,对吗?

只有在使用两个通配符时才会出现此问题。此外,使用另一个泛型类型而不是上限工作:

// All these are fine
Parser<? extends MyConfig, MyConfig>
Parser<MyConfig, ? super MyConfig>
<J extends MyConfig> void test(Parser<J, ? super MyConfig> parser)

我在这里缺少什么?我可以用我的生产者 - 消费者Parser做什么?

编辑:我发现更令人困惑的事情:使用Config的子接口而不是子类工作,即编译完全正常:

interface SpecialConfig extends Config {}
Parser<? extends SpecialConfig, ? super SpecialConfig> specialParser;

0 个答案:

没有答案