Java 泛型类型与旧式泛型的性能差异?
我想知道使用 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;
}
泛型版本代码看起来(非常)稍微简单,因为不需要显式转换。但我的问题是,运行时是否有任何真正的区别,或者字节码中是否仍然存在这种转换?还有其他区别吗?
I am wondering if there is any difference in runtime between a generic container implemented using the language features for generics, introduced Java 1.5, compared to doing it with just inheritance and explicit typecasts. And if there is, which would give the highest performance.
To be specific, lets say I have a base class and a subclass:
public class Base { }
public class Sub extends Base { }
And I define a container type in terms of the base class. Then what I am interested in is what happens when a container instance is known to contain a certain subclass. Before 1.5 I would have no choice but to implement the container like this (never mind that it is too simplified to make actual sense):
public class OldstyleContainer {
private Base x;
public void set(Base x) { this.x = x; }
public Base get() { return x; }
}
And a use of the class where the specific type of the known element is known could look like this:
public Sub oldstylePut(OldstyleContainer c, Sub s) {
Sub t = (Sub) c.get();
c.set(s);
return t;
}
Now, with the language features for generics, I would instead define the container like this:
public class GenericsContainer<T extends Base> {
private T x;
public void set(T x) { this.x = x; }
public T get() { return x; }
}
And the corresponding use would be like this:
public Sub genericsPut(GenericsContainer<Sub> c, Sub s) {
Sub t = c.get();
c.set(s);
return t;
}
The generic version code looks (very) slightly simpler, because there is no need for an explicit cast. But my question is, is there any real difference in runtime, or does that cast still exist in the byte code? Is there any other difference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
泛型被删除 - 因此,当代码运行时,编译器已经将强制类型转换放入其中。使用泛型时,您不必自己在源代码中执行这些操作。所以不要考虑性能——使用泛型让代码更安全。
Generics are erased - so by the time the code runs the compiler has put the casts in anyway. You just don't have to do them yourself in the source code when using Generics. So don't consider performance - use Generics to make code safer.
否 通用信息在运行时不可用,这是其唯一的编译时功能。
No Generic information isn't available at runtime, its only compile time feature.