我在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正在使用这种语法<?>.
有人可以澄清一下它对我的代码的不同之处和影响吗?如果我不一致,我可能会引入一个错误吗?
答案 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
的较短版本。