2016-07-27 60 views
2

我遇到过不清楚如何编译代码的情况,虽然可以通过在每个子类中创建一个新方法而不是超类中的一个方法来轻松解决该问题(但看起来很丑!)我“已经简化了我的代码,让我先从一个类的链(我宣布他们的静态只是为了方便):Java嵌套的泛型:应该是什么形式的参数类型?

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> { 
    ... 
} 

和所谓的 “检查” 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或列表的一些其他的扩展,而且还callCheck应与这些后代只要工作,以及(如代码

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

作品,其中SomeM延伸M < ...>)

+0

此代码编译使用Java 1.8.0_77和设置parmae​​ter键入到M – ghg565

+0

是的,但是接下来有两个警告:原始类型和类型安全......没有它可能吗?否则,使用泛型没有多大意义...... –

回答

0

首先,我摆脱了M,这是没用的第一个类型参数。 UM的机体中没有使用,而且只出现一次,另一个界限定义为? extends U,但由于U extends U0只是相当于? extends U0。 (如果这是不是你真正的代码和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()); 
+0

谢谢,这正是我需要的! –

+0

经过一番思考,我意识到如果有另一个'M'的后代使用例如'MyList2'而不是'List',那么'callCheck'将不起作用: –

+0

这是代码: static class M2扩展M > { @Override public boolean check(MyList2 <?extends U1> c){ return!c.isEmpty()&& c.get(0).x> 0; (new M1());'不会工作,而且'new M2()。check(new MyList1());'won'因为'M2'的方法'check'可能会使用'MyList1'中声明的某些方法,而'MyList'中不存在。 –