繁体   English   中英

Java泛型,来自C ++模板

[英]Java generics, coming from C++ templates

我发现以下代码在Java中引人注目:

    ArrayList<String> l1 = new ArrayList<String>();
    ArrayList<Integer> l2 = new ArrayList<Integer>();
    System.out.println(l1.getClass() == l2.getClass()); // true
    System.out.println(l2.getClass().isAssignableFrom(l1.getClass())); // true too
    //ArrayList<Integer> l3 = l1; // won't compile though

我不太了解“ isAssignableFrom”的详细信息。 当然,我希望编译器停止l3 = l2,但这似乎与上一行矛盾? (我确定这里有一些细微之处,这就是我所追求的:-)

编译后,所有<Blah>信息都会被删除。 就字节码而言,它们都是同一类。

在编译过程中,将检查它们的一致性和兼容性。

因此,当它检查l2.getClass().isAssignableFrom(l1.getClass()) ,是说is ArrayList assignable from ArrayList? 答案是肯定的。 但是因为在编译期间它仍然具有类型信息,所以不允许这样做。

这是由Java的泛型实现(而不是草率)造成的,即Type Erasure

基本上,编译器会擦除类型信息(例如: ArrayList<String>ArrayList<Integer>都变为ArrayList ),并在必要时添加强制类型转换。 在运行时, l1l2之间没有类型区别,但是编译器不允许您执行赋值-因为知道类型是不同的。

这是因为删除泛型。

isAssignableFrom()正在测试这些类是否相同,或者第二个类是否是第一个的超类或超接口。

正如其他答案所述,泛型在编译时被删除,因此它们对该方法的输出没有影响。 只有基类才重要。

参考: Class.isAssignableFrom()

您想要的内容可能已经由getType()方法提供,并且l1.getType()应该返回ArrayList<String> ,而l2.getType()应该返回ArrayList<Integer>

不幸的是,Java在Object上没有getType() 在两种情况下, getClass()返回ArrayList

由于您发现l1.getClass() == l2.getClass()为真,因此l2.getClass().isAssignableFrom(l1.getClass())应该很明显( x.isAssignableFrom(x)始终为true,没有?)。 您真正的问题是为什么l1.getClass() == l2.getClass()为true,这是由于擦除所致。 在运行时只有一个类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM