[英]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
:
B
是A
的亞型 instanceof B
的instanceof A
也是instanceof A
的instanceof 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)
然后,正如這里明確說明的那樣, a
和b
必須具有相同的類型List<T>
,用於類型參數<T extends A>
某些捕獲轉換。
由於List<B>
和List<C>
是兩種不同的類型,因此不能將它們作為test
實際參數混合使用。 此外,即使B
和C
是A
子類型,泛型也是不變的,因此List<B>
和List<C>
都不是List<A>
。
從而,
test(new ArrayList<B>(), new ArrayList<C>()); // error!!! doesn't compile!!!
不編譯,這是預期的行為。
java.lang.ArrayStoreException
關於泛型類型規則:
List<Animal> animals = new ArrayList<Dog>()
? List
與List<Object>
不同之處, List<Object>
與List<?>
使用super
和extends
:
Java Generics: What is PECS?
extends
消費者super
” super
和extends
之間有什么區別 <E extends Number>
和<Number>
之間有什么區別? List<? extends Number>
List<? extends Number>
數據結構? (你不能!) 關於實際的通用錯誤:
這不是一個錯誤,只是泛型是復雜的。 嘗試將第二種測試方法更改為:
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.