在Java Integer延伸NumberJava泛型奇怪的行爲
然後下面的代碼是編譯:
List<Number> list1 = null;
List<? super Integer> list2 = null;
list2 = list1;
儘管此代碼是未編譯:
List<? super Number> list1 = null;
List<? extends Integer> list2= null;
list1 = list2;
的問題是爲什麼?
在Java Integer延伸NumberJava泛型奇怪的行爲
然後下面的代碼是編譯:
List<Number> list1 = null;
List<? super Integer> list2 = null;
list2 = list1;
儘管此代碼是未編譯:
List<? super Number> list1 = null;
List<? extends Integer> list2= null;
list1 = list2;
的問題是爲什麼?
讓我們看看會去錯的,如果它會編譯:
// Suppose list1, and list2 are initialized like this
List<? super Number> list1 = new ArrayList<Object>(); // valid assignment
List<? extends Integer> list2 = new ArrayList<Integer>(); // valid
// had this been valid, list1 and list2 both point to ArrayList<Integer>
list1 = list2;
// This is fine, as list1 declared type is `List<? super Number>`
list1.add(new Float(2.4f));
// The below code will compile fine, as list2.get(0) type is Integer.
// But it would throw ClassCastException at runtime.
Integer in = list2.get(0);
所以,爲了避免它運行時,編譯器給你一個編譯時錯誤。
但是,對於第一種情況,您已以某種方式反轉了分配,因此2個代碼之間的比較沒有意義。將第一個代碼更改爲:
List<Number> list1 = null;
List<? super Integer> list2 = null;
list1 = list2;
它也會失敗。
另外,在第二個代碼中反轉賦值也會導致代碼無法編譯。
一些解釋:
那你必須記住的是,超類引用指向子類對象,而不是相反。如果可以從list1
捕獲轉換的所有列表也可以從已聲明的類型list2
捕獲轉換,那麼轉讓list2 = list1
將是有效的,否則它將無法編譯。
對於第一代碼:
List<? super Integer>
可以捕獲轉換爲以下列表:
List<Integer>
List<Number>
List<Object>
List<Serializable>
由於List<Number>
有沒有在列表中,那麼分配list2 = list1
是有效的,因爲list1
只能指向一個List<Number>
。但是,反向分配list1 = list2
無效,因爲List<Integer>
不是List<Number>
的子類型。
類似地,對於第二代碼:
List<? super Number>
可以捕獲轉換爲:
List<Object>
List<Serializable>
List<Number>
List<? extends Integer>
可以捕獲轉換爲:
List<Integer>
由於List<Integer>
未捕獲兌換從List<? super Number>
,所以list1 = list2
是無效的。
此外,由於List<Object>
和其他所有列表都不能從List<? extends Integer>
捕獲轉換,所以list2 = list1
也是無效的。
(1)在第一個示例中,List<Number>
由List<? super Integer>
「捕獲」。 A List<Number>
是List<? super Integer>
。
(2)但在第二個示例中,List<? extends Integer>
是而不是由List<? super Number>
捕獲。
例如,您可以添加Number
s到List<? super Number>
,但你不能非Integer
Number
s到List<? extends Integer>
補充。
List<? super Number> list1 = new ArrayList<Number>();
list1.add(0.5); //okay
List<? extends Integer> list2 = new ArrayList<Integer>();
list2.add(0.5); //not okay
因此,你不能分配list1
爲list2
,因爲list2
不支持一切的list1
類型應該。
我不是要將數字添加到List <?擴展Integer>。我正在嘗試將Integer添加到List <?超級號碼>,但它不起作用 –
但@Babibu,如果您要將'list1'設置爲'list2',則'list1'的類型必須支持'list2'的所有操作。 –
沒有人添加任何東西,有一個嘗試的任務。 –
您是否注意到您的作業在兩個代碼中均被顛倒過來。將第一個代碼更改爲 - 「list1 = list2」,並且它也不會編譯。 –