我想知道使用泛型的语言特性(引入Java 1.5)实现的通用容器与仅使用继承和显式类型转换相比,运行时是否存在任何差异。如果有的话,这会带来最高的性能。
具体来说,假设我有一个基类和一个子类:
public class Base { }
public class Sub extends Base { }
我根据基类定义容器类型。那么我感兴趣的是当已知容器实例包含某个子类时会发生什么。在1.5之前,我别无选择,只能实现这样的容器(更别提它太简单了,不能真正理解):
public class OldstyleContainer {
private Base x;
public void set(Base x) { this.x = x; }
public Base get() { return x; }
}
使用已知元素的特定类型的类可能如下所示:
public Sub oldstylePut(OldstyleContainer c, Sub s) {
Sub t = (Sub) c.get();
c.set(s);
return t;
}
现在,有了泛型的语言功能,我会改为像这样定义容器:
public class GenericsContainer<T extends Base> {
private T x;
public void set(T x) { this.x = x; }
public T get() { return x; }
}
相应的用法是这样的:
public Sub genericsPut(GenericsContainer<Sub> c, Sub s) {
Sub t = c.get();
c.set(s);
return t;
}
通用版本代码看起来(非常)稍微简单,因为不需要显式转换。但我的问题是,在运行时中是否有任何真正的区别,或者该字节代码中是否仍存在该转换?还有其他区别吗?
答案 0 :(得分:3)
否通用信息在运行时不可用,它是唯一的编译时功能。
泛型是通过类型擦除实现的:泛型类型信息仅在编译时出现,然后由编译器擦除。
答案 1 :(得分:3)
泛型被删除 - 所以当代码运行时,编译器无论如何都会抛出转换。使用泛型时,您不必在源代码中自己完成它们。因此,不要考虑性能 - 使用泛型来使代码更安全。