Java嵌套泛型:形式参数类型应该是什么?

时间:2016-07-27 16:16:52

标签: java generics inheritance

我遇到过一个不清楚如何编译代码的情况,虽然可以通过在每个子类中创建一个新方法而不是在超类中使用一个方法来轻松解决(但这看起来很难看!)我已经简化了我的代码,所以我从一系列类开始(为了方便我将它们声明为静态):

interface U0 { }
static class U1 implements U0 {
    public int x = 1;
}
static class U2 extends U1 { }

然后,有一个抽象类用某个容器做某事:

static abstract class M<U extends U0, C extends List<? extends U>> {
    C field;
    public abstract boolean check(C c);
}

以及作用于U1或U1的任何后代(例如,U2)的派生类的示例:

static class M1 extends M<U1, List<? extends U1>> {

    @Override
    public boolean check(List<? extends U1> c) {
        return !c.isEmpty() && c.get(0).x > 0;
    }

}

现在,让我们说我希望扩展容器,首先添加一个泛型类:

static class MyList<U extends U0> extends ArrayList<U> {
    ...
}

和派生类调用&#34;检查&#34; M的方法:

static class MyList1 extends MyList<U2> {
    void test() {
        M1 m1 = new M1();
        m1.check(this);
    }
}

到目前为止所有这些都有效,但现在我希望更换这些行

M1 m1 = new M1();
m1.check(this);

只需一个电话

callCheck(new M1());

到MyList中声明的某个方法。因此,类MyList现在变为

static class MyList<U extends U0> extends ArrayList<U> {
    void callCheck(??? m) {
        m.check(this);
    }
}

参数m的类型应该是什么?

另请注意,M可能有其他后代,例如C = MyList1或List的其他扩展,但仍然callCheck也应该与这些后代一起工作(只要代码

SomeM someM = new SomeM();
someM.check(this);

有效,其中SomeM扩展M&lt; ...&gt;)

1 个答案:

答案 0 :(得分:0)

首先,我摆脱了M的第一个类型参数,这是无用的。 UM的正文中未使用? extends U,只会在另一个作为U extends U0的另一个定义中出现,但由于? extends U0仅等于{{1} }}。 (如果这不是你真正的代码而且在某个地方使用了U,那么它可能会被加入一些想法。)

编译:

interface U0 { }
static class U1 implements U0 {
    public int x = 1;
}
static class U2 extends U1 { }

static abstract class M<C extends List<? extends U0>> {
    C field;
    public abstract boolean check(C c);
}

static class M1 extends M<List<? extends U1>> {

    @Override
    public boolean check(List<? extends U1> c) {
        return !c.isEmpty() && c.get(0).x > 0;
    }

}

static class MyList<U extends U0> extends ArrayList<U> {
    void callCheck(M<? super MyList<U>> m) {
        m.check(this);
    }
}

static class MyList1 extends MyList<U2> {
}

//...
new MyList1().callCheck(new M1());