不同Java类型擦除和泛型类型格式的优点

时间:2018-05-15 18:56:42

标签: java templates generics types

我在Java中实现了一个使用泛型的库。根据我的理解,后来在Java中引入了泛型类型,以提供类似于C ++中的模板的功能,同时还保持向后兼容性。话虽如此,运行时的参数化类型AVLTree<K, V>只显示为 AVLTree,因此名称&#34; Type Erasure。&#34;

我发现以下三种编写类定义的方法是等效的,因为编译器没有抱怨,也没有得到与类型相关的任何奇怪的运行时问题。我没有使用反射,所以我没有看到该领域的好处。

我被告知不要使用它:

AVLTree<K extends Comparable<K>, V>
相反,他们说,使用这个:

AVLTree<K extends Object & Comparable<? super K>, V>

但是,以下情况也没关系:

AVLTree<K extends Comparable<? super K>, V>

我已经读过,如果你可以避免使用SomeClass<E>,那么较新的Java正在使用这种语法<?>.有人可以澄清一下它对我的代码的不同之处和影响吗?如果我不一致,我可能会引入一个错误吗?

1 个答案:

答案 0 :(得分:1)

嗯,他们应该争辩他们的决定(或者邀请他们来这里,这总是一个不错的选择)。严格来说,它们确实有意义,但不是那么多。

声明AVLTree<K extends Comparable<? super K>, V>表示您可以通过家长比较孩子(通过? super K)。例如? extends CharSequence,您可以比较任何 CharSequence,而不仅仅是String。这些是the famous PECS下的标准声明。

说实话,我很少这样做(可能是我不经常暴露我的API),所以我通常这样做:

K extends Comparable<K>

这样你就不会引入任何错误,你只会限制可以被调用的api,显然如果你关心这个。

另一方面,<?>不是更新或更旧的语法,它只是说任何类型,你很少想要那个IMO。例如,声明这样的List<?>将使其成为只读,并且您将从中获取的对象仅为Object,这只是? extends Object的较短版本。