我找到了一種通過泛型型別將浮點數添加到整數陣列的方法。我很好奇為什么 Java 在運行時錯誤中沒有捕捉到這一點?我嘗試查看檔案以獲取有關此的任何資訊,但我沒有任何運氣。
例如,假設我有兩個 ArrayList,一個包含整數,一個包含浮點數,如下所示:
ArrayList<Integer> listInt = new ArrayList<>();
ArrayList<Float> listFlt = new ArrayList<>();
listInt.add(6);
listInt.add(71);
listFlt.add(4.92f);
listFlt.add(20.5f);
使用泛型,我可以通過以下方法將浮點數從 listFlt 復制到 listInt 中:
public static <T extends Number, S extends Number> void copy(ArrayList<T> src, ArrayList<S> dest) {
for (int i = 0; i < src.size(); i ) {
Object x = src.get(i);
dest.set(i, (S)x);
}
}
呼叫它:
ClassName.<Float, Integer>copy(listFlt, listInt);
現在,當我列印 listInt 時,它顯示:
4.92
20.5
當涉及泛型時,如何將物件轉換為整數?listInt 如何存盤浮點數?謝謝!
uj5u.com熱心網友回復:
使用泛型,我可以通過這樣的方法將浮點數從 listFlt 復制到 listInt
請注意,在此方法中,您將轉換為型別引數S
:
dest.set(i, (S)x);
這將在您編譯它時導致未經檢查的強制轉換警告(您不應該忽略它!)。
這是允許的,但由于型別擦除,JVM 將無法在編譯時檢查是否允許強制轉換。
這是堆污染的一個示例:由于 Java 語言和型別擦除的規則,您會遇到一種情況,您可以將物件添加到ArrayList
錯誤型別的物件中(在這種情況下:您正在將Float
物件添加到串列應該包含Integer
物件)。
當您只列印串列時,沒有問題,因為在這種情況下,Java 只需要呼叫toString()
串列的元素,并且該方法對所有物件都存在。
但是,當您嘗試將 aInteger
排除在串列之外時,您將獲得ClassCastException
:
ClassName.<Float, Integer>copy(listFlt, listInt);
Integer i = listInt.get(0); // ClassCastException: Float cannot be cast to Integer
這是 Java 規則組合的不幸結果,這部分是因為向后兼容性,以及 Java 使用泛型(型別擦除)的方式。
要記住的一點:不要忽略“未經檢查的強制轉換”警告;它們暗示您的代碼中可能存在堆污染。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/483535.html