這個問題在這里已經有了答案: 為什么陣列是協變的,而泛型是不變的? (9 個回答) 3 天前關閉。
當我只擴展類 Number 時,什么使添加 Pair<String, String> 成為可能?這是否違反了陣列應該只包含相同型別元素的期望?
public class test {
public static void main(String[] args) {
Pair<? extends Number, ? extends Number>[] arr = new Pair[2];
m1(arr);
arr[1] = new Pair<Integer, Integer>(1, 1);
System.out.println(arr[0].x);
System.out.println(arr.getClass().getComponentType());
}
static void m1(Object[] arr) {
arr[0] = new Pair<String, String>("test","test");
}
}
class Pair<T, E> {
public T x;
public E y;
public Pair(T x, E y) {
this.x = x;
this.y = y;
}
}
uj5u.com熱心網友回復:
我們有以下情況:Java 中的繼承是多層次的,而不僅僅是 2 層次。
- 類物件
- 類號(擴展物件)
- 類整數擴展數字
- 類雙擴展數
關系:
- Number、Integer、Double 是物件
- Integer, Double 是數字
- Integer, Double 是物件
所以一個IntegerIS a Number,只是有一些額外的功能。對于Double. 如果Number通過撰寫List<Number> listor List(? extends Number) list(soNumber或其任何子類)告訴陣列(定義、宣告)保存s ,則可以添加任何Number.
如果你Number像這樣創建了一個s陣列:(arr[0] = new Double(2.0);初始化和分配)那么新值是 a Double,但是Double是 a Number,所以新值也仍然是 a Number。所以這是完全有效的。
在您的情況下,您創建了一個Pairs的陣列Number,使整個事情變得更加復雜,但基本原則保持不變:“宣告”型別仍然Number適用于所有這些型別,但分配的值是Doubleor Integer(仍然Number是s)。instanceOf如果需要,您仍然可以稍后通過檢查查看這些值是什么不同的子型別來解決這個問題。
uj5u.com熱心網友回復:
這是Java 中陣列協方差加型別擦除的一個示例。
陣列協方差
Java中的陣列是協變的:如果一個陣列可以處理Integer( Integer[]),而Integer是一個Object,那么這個陣列也可以處理Object,所以可以參考為Object[]。由于 String 也是一個物件,所以事情變得棘手!(在這里和這里進一步閱讀)。
型別擦除
在編譯時檢查泛型型別的正確性,然后在運行時被遺忘/擦除。APair<Double, Double>只是Pair運行時的 a。這就是為什么如果你能像引入m1()方法一樣欺騙編譯器,那么你在運行時就可以了。(在此處進一步閱讀)。
你的代碼解釋
您的arr變數被描述為Pair<? extends Number, ? extends Number>[]. 但請記住,變數只是參考某個物件的名稱。它背后的實際物件只是一個 Pair ( Pair[])陣列。
當您呼叫 時m1(),另一個變數用于參考這個完全相同的陣列,但這次它是一個更通用的變數,可以處理任何物件陣列 ( Object[])。
您會看到在該main方法中創建的實際陣列與用于在整個代碼中參考它的兩種型別的變數兼容。
為了克服陣列協方差,您可以選擇使用一個ArrayList(或您希望的任何其他集合),但是,如您所見,您仍然會遇到物件上的泛型型別擦除問題Pair。像這樣:
public static void main(String[] args) {
List<Pair<? extends Number, ? extends Number>> arr =
new ArrayList<Pair<? extends Number, ? extends Number>>();
m1(arr);
arr.add(new Pair<Integer, Integer>(1, 1));
...
}
static void m1(List arr) {
arr.add(new Pair<String, String>("test","test"));
}
多么迷宮啊?!
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/375641.html
