有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当上限通配符与下限通配符一起使用时,java编译失败

情境:我正在制作一个配置库,其中包含一个表示数据的配置接口和一个解析器接口,如下所示:

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

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

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

  • 我们的解析器可以解析MyConfig,但也可能解析它的超类型=>;我应该使用“超级MyConfig”
  • 我们的解析器可以生成MyConfig,但可能它实际上会生成一个 子类型=>;我应该使用“?扩展MyConfig”

因此,我得出结论:

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

但是,尽管IntelliJ没有抱怨什么,编译(javac 1.8.0131)失败,出现以下错误:

type argument ? extends package.MyConfig is not within bounds of type-variable 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)

我错过了什么?我可以用生产者消费者解析器做什么

编辑:我发现更令人困惑的是:使用Config的子接口而不是子类是可行的,即这样编译非常好:

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

共 (0) 个答案