2016-07-27 282 views
3

我有一個關於泛型的問題。編譯泛型時出現錯誤

我有一個類裏面這個片段(我們稱之爲案例1):

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     C.class, 
     D.class 
    ); 
} 

public interface A {…} 

public class C extends B {…} 

public class D extends B {…} 

public abstract class B implements A {…} 

Android Studio中抱怨,並沒有在上面一行final List…編譯:

不相容的類型
必需列表< 類<?延伸A > >
找到的商品清單< 類<?延伸乙> >

但是,以前我有這個代碼(我們稱之爲案例2):

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     C.class, 
     D.class 
    ); 
} 

public interface A {…} 

public class C implements A {…} 

public class D implements A {…} 

,它編譯。

所以,我試過,只是縮小的問題,改變的情況下1到這個的緣故:

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     B.class 
    ); 
} 

請注意,B實現A,就像C和d的情況下,兩個。但編譯器仍然抱怨。

我想出瞭解這個問題,我讀了Java Language Specification類型和值章節,仍然沒有。

我在StackOverflow搜索,我沒有找到類似的問題。

任何指針? (PS:強制XKCD之前有人這樣做)

+0

爲我編譯好。如果您使用的是Java 7,則可以使用顯式類型參數。 –

+0

Sotiros Delimanolis,它確實是該問題的重複,我想我以前使用了錯誤的術語進行搜索。 –

回答

6

這個問題是一個類型推斷的問題。在Java 8之前,編譯器推斷使用typeList類型來確定Arrays.asList的實例時不夠智能,因此會發生孤立。

試試這個明確的暗示:

final List<Class<? extends A>> typeList = Arrays.<Class<? extends A>>asList(
    B.class 
); 

要進入更詳細,編譯器只是看到這個隔離:

Arrays.asList(
    C.class, 
    D.class 
); 

沒有看到什麼它分配給。它選擇Class<? extends B>而不是Class<? extends A>,因爲這是所有參數共有的最具體的超類型。

+0

哇。好一個。 – Mena

+0

它完美無缺!你很快,很快的StackOverflow不會允許我接受它!謝謝Mark Peters。 –