嵌套递归类型

时间:2018-05-18 19:44:08

标签: java generics

我有以下几组课程:

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上的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);
}

1 个答案:

答案 0 :(得分:2)

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

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