有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java类型将对象强制转换为任何集合类型

我们最近在代码中遇到了一个bug,它基本上与OOPs概念有关

class ABC
{
    String a;
    ABC(){
        a = "abc";
    }
}

public class Main {


    static Object listABC() {
        List<ABC> listOfABC = new ArrayList<>();
        listOfABC.add(new ABC());
        return listOfABC;
    }

    public static void main(String[] args) throws java.lang.Exception {

        List<Long> listLong = (List) Main.listABC();
        System.out.println(listLong.get(0));
    }
}

Output: ABC@642c39d2

这不应该引发运行时异常吗?有人能给我指出正确的方向吗?为什么这段代码不会引发异常


共 (2) 个答案

  1. # 1 楼答案

    泛型类型将被擦除,并且在您的示例中,关于它们的信息在运行时不再存在。它们只是编译时辅助工具。演员名单<;T>;to List也会在编译时丢弃有关类型的信息,尽管它仍然是有效的强制转换

    因此,只要你在每一步都进行法律强制转换,它就会很好地编译。在运行时,列表中关于类型的信息将消失在此处

    如果您试图将get(0)强制转换为Long,那么您将得到一个classcastexception,因为该项本身是ABC

  2. # 2 楼答案

    答案很简单。泛型是编译时组件,以确保编译时兼容性。泛型在编译后消失,因此在运行时不再存在

    由于Object listABC确实返回了一个List,所以(List) Test.listABC();不会抛出异常,因为它实际上返回了一个List是有效的

    您可以将它分配给List<Long> listLong,因为在运行时listLong不再知道它是Long泛型的

    因此,即使看起来是错误的,这也是有效的可执行代码

    还有一个唯一的原因是有一个PrintStream#println(Object)方法,否则您会得到一个Exception,因为您试图用错误的类型调用它,如下面的示例所示

    static Object listABC() {
        List<Test> listOfABC = new ArrayList<>();
        listOfABC.add(new Test());
        return listOfABC;
    }
    
    public static void main(String[] args) throws java.lang.Exception {
    
        List<Long> listLong = (List) Test.listABC();
        System.out.println(listLong.get(0));
        test(listLong.get(0));
    }
    
    private static void test(Long longvalue) {
        System.out.println("TEST");
    }
    

    O/p

    ABC@19e0bfd
    Exception in thread "main" java.lang.ClassCastException: ABC cannot be cast to java.lang.Long
    at ABC.main(ABC.java:19)