考慮以下片段:
Integer a = Integer.valueOf(23);
Double d = (Double) (Number) a; //not unchecked cast
List<String> stringList = new ArrayList<>();
List<Integer> integerList = (List<Integer>)(List<?>)stringList; //unchecked cast
- 從我的理解-只要我們把
Supertype -> Subtype未經檢查的投標記為編譯器不知道,直到運行時,如果該型別代表由Supertype永遠不會匹配SubType。 - 然后在這里 - 為什么
(Double) (Number)a沒有被標記為Unchecked Cast?
uj5u.com熱心網友回復:
未經檢查的強制轉換被標記為編譯器直到運行時才知道 表示的型別
Supertype是否與SubType.
那是不正確的。甚至運行時都不知道您的串列是 aArrayList<String>還是 a ArrayList<Integer>。就運行時而言,您的串列是一個ArrayList(這是因為型別擦除)。這就是運行時無法檢查List<?>將 a轉換為 a 的原因List<String>。運行時不知道 aList<String>是什么——它只知道List. 對于運行時,不需要檢查,因為您只是從Listto 進行轉換List,這總是成功的。事實上,在運行時沒有為這個強制轉換做任何事情——它是一個完全未經檢查的強制轉換。
因此,此代碼運行時不會引發例外:
List<String> stringList = new ArrayList<>();
stringList.add("foo");
List<Integer> integerList = (List<Integer>)(List<?>)stringList;
System.out.println(integerList.size());
它會拋出一個例外,但是,如果你這樣做:
List<String> stringList = new ArrayList<>();
stringList.add("foo");
List<Integer> integerList = (List<Integer>)(List<?>)stringList;
System.out.println(integerList.get(0) - 1);
現在,您正在從串列中獲取一個整數,并對它執行一些特定于整數的操作。但是串列包含"foo",它不是整數。編譯器插入一個隱式強制轉換為強制轉換integerList.get(0)為Integer,并且該轉換失敗。請注意,這是一個已檢查的強制轉換,因為運行時知道 type Integer。
還檢查了從NumbertoDouble的強制轉換,因為運行時知道Double.
旁注:還有“部分未經檢查的強制轉換”,例如從Objectto強制轉換ArrayList<String>。運行時可以檢查 是否Object為ArrayList,但無法檢查是否為字串陣列串列。
在此處查看已檢查和未檢查的所有規則。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/342897.html
下一篇:去泛型-聯合
