键入将对象转换为任何Collection类型

Rac*_*gon 5 java oop collections

我们最近在代码中遇到了一个与OOP概念基本相关的错误.

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:ABC @ 642c39d2

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

Jas*_*n C 7

通用类型将被删除,并且在您的示例中,有关它们的信息在运行时不再存在.他们只是编译辅助工具.将List <T>转换为List也会在编译时丢弃有关类型的信息,尽管它仍然是有效的强制转换.

因此,只要您在每一步都进行合法演员表,那么它就可以正常编译.在运行时,列表中的类型信息已经消失.

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

  • 实际的故事更复杂,最好说_在这个特定的例子中,泛型类型已经消失了.例如,字段或方法参数上的类型参数可用于反射; 如果使用非泛型类实现泛型接口,则您使用的类型文字也可用.在Java中,擦除是一团糟. (3认同)
  • 简而言之:作为泛型类型实例的对象(在您的情况下是`ArrayList`)不知道它的类型参数,但是还有很多其他情况会发生泛型类型---在对象的字段上,方法不同的规则适用于每个个案,整个画面不是很漂亮. (3认同)
  • @rmagon简而言之:这意味着,从技术上讲,在某些情况下*关于类型参数*的*信息*在运行时存在.只是该信息的形式或位置与A <T>和A之间的类型转换无关.也就是说,一般声明"关于泛型类型的信息在运行时消失"并不是真正的*真正的fsv"信息"; 它只是不适用于你的情况. (2认同)