簡體   English   中英

Java多個泛型集合參數編譯錯誤

[英]Java multiple generic collection parameters compile error

這么奇怪! 請先查看代碼:

public class A {}

public class B extends A {}

public class C extends A {}

public class TestMain {

    public <T extends A> void test(T a, T b) {}

    public <T extends A> void test(List<T> a, List<T> b) {}

    public void test1(List<? extends A> a, List<? extends A> b) {}

    public static void main(String[] args) {
        new TestMain().test(new B(), new C());
        new TestMain().test(new ArrayList<C>(), new ArrayList<C>());
        new TestMain().test(new ArrayList<B>(), new ArrayList<C>());
        new TestMain().test1(new ArrayList<B>(), new ArrayList<C>());
    }
}

語句new TestMain().test(new ArrayList<B>(), new ArrayList<C>())收到編譯錯誤:

綁定不匹配:類型TestMain的泛型方法測試(T,T)不適用於參數(ArrayList<B>, ArrayList<C>) 推斷類型ArrayList<? extends A> ArrayList<? extends A>不是有界參數<T extends A>的有效替代

然而:

 new TestMain().test(new B(), new C())  --> compiled ok

 new TestMain().test(new ArrayList<C>(), new ArrayList<C>()) --> compiled ok

 new TestMain().test1(new ArrayList<B>(), new ArrayList<C>()) --> compiled ok

如果我們在方法名稱之前定義泛型,則第二個通用List參數的類型似乎必須與第一個相同。 但是如果我們在參數中定義泛型,則沒有限制。

它是編譯程序的功能還是錯誤? 有關於它的一些文件嗎?

絕對沒有錯誤; 你只是誤解了泛型中的子類型規則。

既然我們有B extends A

  • BA的亞型
  • instanceof Binstanceof A也是instanceof Ainstanceof A

由於Java數組是協變的:

  • B[]A[]的子類型
  • instanceof B[]instanceof A[]也是instanceof A[]instanceof A[]

但是,Java泛型是不變的:

  • List<B>不是List<A>的子類型
  • instanceof List<B>instanceof List<A>不是instanceof List<A>instanceof List<A>

當您具有以下通用方法聲明時:

public <T extends A> void test(List<T> a, List<T> b) 

然后,正如這里明確說明的那樣, ab必須具有相同的類型List<T> ,用於類型參數<T extends A>某些捕獲轉換。

由於List<B>List<C>是兩種不同的類型,因此不能將它們作為test實際參數混合使用。 此外,即使BCA子類型,泛型也是不變的,因此List<B>List<C>都不是List<A>

從而,

test(new ArrayList<B>(), new ArrayList<C>()); // error!!! doesn't compile!!!

不編譯,這是預期的行為。

也可以看看

相關問題

關於泛型類型規則:

使用superextends

關於實際的通用錯誤:

這不是一個錯誤,只是泛型是復雜的。 嘗試將第二種測試方法更改為:

    public <T extends A, K extends A> void test(List<T> a, List<K> b) {

基本上在你所擁有的東西中沒有類型T可以滿足你傳遞的內容,不像第一種方法,其中B和C只是被視為A.這種行為的實際名稱逃脫了我但是應該有很多文獻中的例子。

簡而言之,即使B是A的孩子,List <B>也不是List <A>的孩子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM