范型代码和Java虚拟机
-
关键知识:类型擦除
Java的范型是编译器层次的范型,而在Java虚拟机上并没有范型类。在程序中定义的范型类,都会被擦除类型变量,生成一个与限定类型绑定的raw type。
例如:
<T>类型被擦除后,变为Object类,<T entends Comparable & Serializable>的类型被擦除后,变为第一个限定类Comparable接口。对于多个限定类型的范型定义,编译器会插入强制类型转换。因此tagging type的接口应该放在范型类型列表的最后。
-
范型表达式
由于类型擦除,编译器在处理返回值时,会插入强制类型转换。
-
范型方法
范型类
Pair<T>包含方法setSecond(T newValue)。类型擦除后,虚拟机上只对应raw type方法setSecond(Object newValue)。Pair的派生类DateInterval extends Pair<LocalDate>。这个类重载了setSecond(LocalDate)。此时,在
DateInterval中实际上有2个setSecond方法:setSecond(LocalDate)setSecond(Object)
而范型类在继承的时候由于类型擦除,会引起多态失效。见下面的示例:
DateInterval interval = new DateInterval(...); Pair<LocalDate> pair = interval; pair.setSecond(aDate)而实际运行中,Java虚拟机能够处理好这种多态。这是因为编译器会自动在DateInterval类中生成一个桥函数,重载了
Pair中的setSecond(Object):class DateInterval extends Pair<LocalDate> { ... public void setSecond(LocalDate second) {...} ... public void setSecond(Object second) { setSecond((LocalDate)second); } ... }反之,
DateInterval中的getSecond()也生成桥方法:public LocalDate getSecond() { return (Date) super.getSecond().clone(); }再总结一下Java范型转换:
- 虚拟机中没有范型,只有普通的类和方法
- 所有的类型参数,都被替代为限定类型(默认为Object)
- 编译器用桥方法来保持多态
- 为了保持类型安全,必要时插入强制类型转换
-
调用遗留代码
- 把范型类传入遗留代码:产生警告。
- 把遗留数据赋给范型类型:产生警告。
有警告就有警告吧,不会比没有范型的时候更糟,最大的问题就是执行时抛出一个异常。







网友评论