ClassCastException
是 Java 中常見的運行時異常,它通常發(fā)生在試圖將一個對象強制轉(zhuǎn)換為不兼容的類型時。這種轉(zhuǎn)換在編譯時是合法的,但在運行時會檢查對象的實際類型,如果與目標類型不匹配,就會拋出 ClassCastException
。
以下是可能導(dǎo)致 ClassCastException
的一些常見情況:
直接實例化接口或抽象類:
interface MyInterface { }
public class Main {
public static void main(String[] args) {
MyInterface obj = new MyInterface() {}; // 編譯通過,但運行時拋出 ClassCastException
}
}
在這個例子中,盡管我們創(chuàng)建了一個匿名內(nèi)部類實現(xiàn)了 MyInterface
,但直接實例化接口本身會導(dǎo)致 ClassCastException
。
錯誤的類型轉(zhuǎn)換:
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
List<Integer> integerList = (List<Integer>) stringList; // 運行時拋出 ClassCastException
這里我們試圖將一個 List<String>
強制轉(zhuǎn)換為 List<Integer>
,這是不合法的,因為列表中的元素類型不匹配。
數(shù)組類型轉(zhuǎn)換:
Object[] objects = new String[1];
Integer[] integers = (Integer[]) objects; // 運行時拋出 ClassCastException
在這個例子中,盡管 objects
數(shù)組可以容納一個對象,但我們試圖將其強制轉(zhuǎn)換為 Integer[]
數(shù)組,這會導(dǎo)致 ClassCastException
。
泛型類型擦除: 由于 Java 的泛型是類型擦除的,因此在運行時無法檢查泛型的實際類型。例如:
List<String> stringList = new ArrayList<>();
List rawList = stringList;
rawList.add(1); // 編譯通過,但運行時可能導(dǎo)致 ClassCastException
盡管 rawList
是 List
類型的,但由于類型擦除,無法確保它只包含 String
對象。
要避免 ClassCastException
,可以在強制轉(zhuǎn)換之前進行類型檢查,或者使用更安全的泛型操作。例如:
List<String> stringList = new ArrayList<>();
if (stringList instanceof List<?> && ((List<?>) stringList).isEmpty()) {
List<?> rawList = stringList;
rawList.add(1); // 這里不會拋出 ClassCastException,因為進行了類型檢查
}