首页 > 解决方案 > 实现上界泛型方法

问题描述

我在构建一个有点循环的通用配置时遇到了麻烦。我需要一个为通用“容器”接口提供吸气剂的“状态”接口。其方法上的容器接口需要接受一个通用的“状态”作为参数之一。我尝试了各种选项(真正的循环泛型类参数,下面的各种变体),但我下面的内容最接近我认为我需要的内容:

interface Container<K> {
    <C extends Container<K>,S extends State<K,C>> C setData(K key, Object val,S state);
}

interface State<K,C extends Container<K>>{
    C getContainer();
}

class BasicContainer<K> implements Container<K> {
    public <C extends BasicContainer<K>, S extends State<K,C>> C setData(K key, Object val, S state) { return this;}
}

class BasicState<K> implements State<K,BasicContainer<K>> {
    BasicContainer<K> container = new BasicContainer<K>();
    public BasicContainer<K> getContainer(){
        return container;
    }
}

唉,编译器是给这个方法出名methods have same erasure yet neither overrides the otherBasicContainer。我相信这是因为 whileC extends BasicContainer<K>是的子类型C extends Container<K>S extends State<K,C>不是in子类型。S extends State<K,C>Container<K>

关于如何通过所需配置完成的任何建议?

更新 我将需要其他实现Container也需要与State实现一起使用,但State实现不会返回这些实现。这就是类的循环参数失败的地方。

标签: javagenericsbounded-wildcardgeneric-method

解决方案


它看起来C应该是Container接口上的类型参数,比如K.

通常,如果Foo是 的超类型BarBar 则不能为来自 的方法的泛型类型参数添加额外的约束Foo。这只是遵循 Liskov 替换原则:anyBar必须能够用于任何aFoo可以用于的东西。

C extends BasicContainer<K>在 的类型参数中进行约束BasicContainer.setData,当Container.setData只有约束时C extends Container<K>,具体违反此规则。

您可以做的是将上限C作为类型参数 onContainer,并将其设置为BasicContainer.

这可能类似于以下内容之一:

interface Container<K, C extends Container<K, C>> {
    <S extends State<K,C>> C setData(K key, Object val,S state);
}
class BasicContainer<K> implements Container<K, BasicContainer<K>> { ... }

...或者,如果您发现需要额外的泛型,

interface Container<K, C extends Container<K, C>> {
    <C2 extends C, S extends State<K,C>> C2 setData(K key, Object val,S state);
}
class BasicContainer<K> implements Container<K, BasicContainer<K>> { ... }

(虽然坦率地说,第二个版本几乎肯定不是你想要的)。


推荐阅读