因此,我无法为正确的设计缠住头。

我的应用程序有两个控制状态的关键对象,它们需要彼此交互:ItemList,ItemState。它们每个都依赖于通用的ITEM_TYPE,因此它们可以在不同的上下文中运行。它们也是抽象的,以允许依赖于ITEM_TYPE的行为。

这两部分都需要知道通用类型,而且,由于它们彼此交谈,因此他们需要知道彼此的通用类型。 (ItemList 实例需要知道其ItemState字段是ItemState ,反之亦然)。

我当前的解决方案有效,但是似乎很糟糕。一定有更好的方法。这就是我现在正在做的:

public abstract class ItemState<
  ITEM_TYPE,
  STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
  LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {

}
public abstract class ItemList<
  ITEM_TYPE,
  STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
  LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {

}

然后,一个实现类可能看起来像:
class StringState extends ItemState<String, StringState, StringList> {

}
class StringList extends ItemList<String, StringState, StringList> {

}

请注意,对于ItemState,STATE_TYPE是对实现类的引用,同样对ItemList / LIST_TYPE也是如此。

如果我仅使ItemState成为ItemList的内部类,确实会解决我的问题,因为将存在隐式绑定并且它们可以共享通用声明,但是两个类都非常大且独立,因此我不希望这样做。

有什么建议?

编辑:作为评论的反例:
public abstract class ItemState<ITEM_TYPE> {
  public abstract ItemList getItemList();
  public void doSomething() {
    // This should not compile because abstract super class has
    // no idea what the generic type of getItemList() is
    ITEM_TYPE item = this.getItemList.getItem();
  }
}

编辑2:我认为我能想到的最好的解决方案是使ItemList / ItemState继承一种或多种方式,以便它们可以充当同一类。我不喜欢这种解决方案,因为它覆盖了关注点分离,但是它使泛型更易于管理。

旁注:我的实际应用程序在4个交错的类中遇到了这个问题,为简单起见,我只使用了2个。实际上,泛型是如此糟糕,以至于难以理解且难以重构(每个类仅约4行,仅泛型声明)。我现在已经将这4个类做成一个垂直继承层次结构

杨俊杰的解决方案很好

最佳答案

我认为您在声明这两个类时可能只引用通用类型ITEM_TYPE。

我能够编译以下代码而不会出错。

public abstract class ItemList<ITEM_TYPE> {
    public abstract ItemState<ITEM_TYPE> getState();

    public abstract ITEM_TYPE getItem();
}

public abstract class ItemState<ITEM_TYPE> {
    public abstract ItemList<ITEM_TYPE> getItemList();

    public void doSomething() {
        ITEM_TYPE item = getItemList().getItem();
        System.out.println(item);
    }
}

public class StringList extends ItemList<String> {
    @Override
    public StringState getState() {
        return new StringState();
    }

    @Override
    public String getItem() {
        return "";
    }
}

public class StringState extends ItemState<String> {
    @Override
    public StringList getItemList() {
        return new StringList();
    }
}

08-27 14:12