ClassCastException
是 Java 中常见的运行时异常,它通常发生在试图将一个对象强制转换为不兼容的类型时。这种转换在编译时是合法的,但在运行时会检查对象的实际类型,如果与目标类型不匹配,就会抛出 ClassCastException
。
以下是可能导致 ClassCastException
的一些常见情况:
-
直接实例化接口或抽象类:
interface MyInterface { } public class Main { public static void main(String[] args) { MyInterface obj = new MyInterface() {}; // 编译通过,但运行时抛出 ClassCastException } }
在这个例子中,尽管我们创建了一个匿名内部类实现了
MyInterface
,但直接实例化接口本身会导致ClassCastException
。 -
错误的类型转换:
List
stringList = new ArrayList<>(); stringList.add("Hello"); List integerList = (List ) stringList; // 运行时抛出 ClassCastException 这里我们试图将一个
List
强制转换为List
,这是不合法的,因为列表中的元素类型不匹配。 -
数组类型转换:
Object[] objects = new String[1]; Integer[] integers = (Integer[]) objects; // 运行时抛出 ClassCastException
在这个例子中,尽管
objects
数组可以容纳一个对象,但我们试图将其强制转换为Integer[]
数组,这会导致ClassCastException
。 -
泛型类型擦除: 由于 Java 的泛型是类型擦除的,因此在运行时无法检查泛型的实际类型。例如:
List
stringList = new ArrayList<>(); List rawList = stringList; rawList.add(1); // 编译通过,但运行时可能导致 ClassCastException 尽管
rawList
是List
类型的,但由于类型擦除,无法确保它只包含String
对象。
要避免 ClassCastException
,可以在强制转换之前进行类型检查,或者使用更安全的泛型操作。例如:
ListstringList = new ArrayList<>(); if (stringList instanceof List> && ((List>) stringList).isEmpty()) { List> rawList = stringList; rawList.add(1); // 这里不会抛出 ClassCastException,因为进行了类型检查 }