Java递归通用和通配符

时间:2017-02-01 01:03:28

标签: java generics recursion wildcard

你好,我有一个关于Java的问题,并使用带有递归泛型的通配符。我有以下界面

public interface Recursive<R extends Recursive<R>> {}

和另一个使用递归接口的插件

public interface Use<R extends Recursive<R>> {}

现在我的界面看起来像这样

public interface Base<R extends Recursive<R>> {
    Use<R>[] getUses();
}

并且基于该类我想要一个使用像这样的通配符的派生类

public class Derived extends Base<Recursive<?>> {
    Use<?>[] getUses();
}

这是不允许的,但我怎么能设法说我的通用类型是适合的一切?

2 个答案:

答案 0 :(得分:0)

问题是Recursive< ? >不满足Base类型参数的约束。

如果您想延长Base< R >,则必须为R提供Recursive< R >的内容。 Recursive< ? >不够好,因为编译器无法弄清楚Recursive< ? > extends Recursive< Recursive< ? > >

扩展Base未知类型并没有多大意义,但您可以声明它们的异构集合:

Collection< Base< ? > > cb; // ok for some reason
Collection< Base< Recursive< ? > > > cbr; // not ok!

从您的评论我们知道Base看起来像

public abstract class Base< R extends Recursive< R > > {
    public abstract R[] foo();
}

对于每个符合条件的R,您当然可以

public class Derived< R extends Recursive< R > > extends Base< R > {
    @Override public R[] foo() {
        return ( R[] )new Object[] { r1, r2 };
    }
}

但是你的评论并不清楚这是你想要的。您知道您希望R使用的具体Derived是什么吗?

编辑以下编译。那就够了吗?

interface Recursive< R extends Recursive< R > > {}
abstract class Base< R extends Recursive< ? extends R > > {
    abstract public R[] foo();
}
class Derived extends Base< Recursive< ? > > {
    public Recursive< ? >[] foo() { return null; }
}

编辑2 调整原始帖子的更改:

interface Recursive< R extends Recursive< R > > {}
interface Use< R extends Recursive< ? extends R > > {}
abstract class Base< R extends Recursive< ? extends R > > {
    abstract public Use< R >[] foo();
}
class Derived extends Base< Recursive< ? > > {
    @Override public Use< Recursive< ? > >[] foo() { return null; }
}

答案 1 :(得分:0)

您需要键入(使用右边界)您的子类,否则编译器无法断言该类的通配符与您的方法返回的相同类型,这是必需的。

试试这个:

public class Derived<R extends Recursive<R>> extends Base<R> {
    Use<R>[] getUses();
}