情况:我正在创建一个配置库,其中包含一个表示数据的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规则:
因此我最终得到了这个:
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;