首页 > 解决方案 > 嵌套递归类型

问题描述

我有以下一组课程:

public interface Policy<DSI extends DupStateInfo<DSI>,
                                SD extends ScenarioData<DSI, SD>,
                                   SS extends ScenarioState<SD, SS>
                                              >
{
   SS apply(SS scenarioState);
}

interface DupStateInfo<DSI extends DupStateInfo<DSI>> {
    String getValue();
    DSI withValue(String newValue);
}
interface ScenarioData<DSI extends DupStateInfo<DSI>, SD extends ScenarioData<DSI, SD>> {
    Collection<DSI> getDupStateInfo();
    SD withDupStateInfo(Collection<DSI> dupStateInfo);
}
interface ScenarioState<SD extends ScenarioState<SD, SS>, SS extends ScenarioState<SD, SS>> {
    SD getScenarioData();
    SS withScenarioData(SD newData);
}

有多种实现,其中的实现DupStateInfo将具有不同的字段。大多数使用的代码都在这些接口级别工作,但它调用了一些抽象方法,这些方法需要特定的实现类来获取特定于该实现的数据。

这无法编译:

error: type argument SD#1 is not within bounds of type-variable SD#2
  where SD#1,DSI,SD#2,SS are type-variables:
    SD#1 extends ScenarioData<DSI,SD#1> declared in interface Policy
    DSI extends DupStateInfo<DSI> declared in interface Policy
    SD#2 extends ScenarioState<SD#2,SS> declared in interface ScenarioState
    SS extends ScenarioState<SD#2,SS> declared in interface ScenarioState

如果我删除SS参数 on Policy,那么它会编译,但是我不能使用完全专业化的ScenarioData.

这些with*方法允许通用代码用新值更新对象,而无需知道所涉及的特定子类。

如果有帮助,ScenarioData 和 ScenerioState 只有一种实现,但 Policy 和 DupStateInfo 有多种实现。

有没有办法使这项工作?

我正在使用 Java 8,但如果需要,也许可以使用 Java 10。

编辑

@SeanVanGorder 指出了类型参数不匹配的问题。如果他想发布答案,我会接受。否则,这就是有效的。

public interface Policy<DSI extends DupStateInfo<DSI>,
                        SD extends ScenarioData<DSI, SD>,
                        SS extends ScenarioState<DSI, SD, SS>
                                   >
{
    SS apply(SS ss);
}

interface DupStateInfo<DSI extends DupStateInfo<DSI>> {
    String getValue();
    DSI withValue(String newValue);
}
interface ScenarioData<DSI extends DupStateInfo<DSI>, SD extends ScenarioData<DSI, SD>> {
    DSI getDupStateInfo();
    SD withDupStateInfo(DSI dupStateInfo);
}
interface ScenarioState<DSI extends DupStateInfo<DSI>, SD extends ScenarioData<DSI, SD>, SS extends ScenarioState<DSI, SD, SS>> {
    SD getScenarioData();
    SS withScenarioData(SD newData);
}

标签: javagenerics

解决方案


SD extends ScenarioState<SD, SS>应该ScenarioData改为扩展:

interface ScenarioState<DSI extends DupStateInfo<DSI>, SD extends ScenarioData<DSI, SD>, SS extends ScenarioState<DSI, SD, SS>>

推荐阅读