将通用列表转换为特定类型时发生ClassCastException

时间:2019-03-27 13:44:04

标签: java

在下面的代码中,当从ClassCastException字符串中获取整数的实际值时,我仅在第6行得到List。但我想在第4行中获得此异常。如您所见,第5行在没有ClassCastException

的情况下是正确的
public static void main(String[] args) {
    List<String> original = Arrays.asList("1", "2", "3");
    Object obj = original;
    List<Integer> li = (List<Integer>)obj;
    System.out.println(li); //[1, 2, 3]
    Integer ei = li.get(0); //java.lang.ClassCastException
}

我知道List仅包含对实际对象(值)的引用,在读取之前对实际内容一无所知。有没有正确的方法将ClassCastException扔到第四行?

4 个答案:

答案 0 :(得分:1)

您已使用Object和强制类型转换绕过了编译器对泛型类型的检查:

List<Integer> li = (List<Integer>) (Object) Arrays.asList("1", "2", "3");
Integer i = li.get(0);

第4行不会得到ClassCastException,因为在运行时由于Type Erasure而没有通用信息。该代码或多或少地被编译为:

List li = (List) Arrays.asList("1", "2", "3"); // all good, still List
Integer i = (Integer) li.get(0); // ClassCastException

答案 1 :(得分:1)

您可以获得的唯一编译时间警告

java: unchecked cast
  required: java.util.List<java.lang.Integer>
  found:    java.lang.Object

可以使用

获得
-Xlint:unchecked

编译参数。
在运行时,这是不可能的,因为始终允许向Object进行向上转换,并且在这种情况下(因为您要锁定Object始终允许从List进行向下转换。

答案 2 :(得分:1)

由于编译器警告正试图告诉您(第4行的警告):完全不检查类型断言中的泛型位(括号中的小东西是非原始类型的强制转换),编译器只是信任您。

这实际上是一个类型断言(您,程序员,是在通知编译器它应该对其中的内容进行推测)。

进行此类操作的唯一方法是遍历该列表中的每个元素,并检查它是否为Integer。

答案 3 :(得分:0)

将对象转换为整数数组需要先转换为字符串,然后转换为整数。

        List<String> original = Arrays.asList("1", "2", "3");
        Object obj = original;
        List<Integer> li = (List<Integer>)obj;
        System.out.println(li); //[1, 2, 3] 
        Integer ei = new Integer(String.valueOf(li.get(0))); //java.lang.ClassCastException

另请参阅how-to-cast-an-object-to-an-int