2016-07-27 112 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'中不存在。 –