【问题标题】:Advantages of different Java type erasures and generic type formats不同 Java 类型擦除和泛型类型格式的优点
【发布时间】:2018-05-15 18:56:41
【问题描述】:

我正在用 Java 实现一个使用泛型的库。据我了解,Java 后期引入了泛型类型,以提供类似于 C++ 中模板的功能,同时也保持向后兼容性。话虽如此,运行时的参数化类型AVLTree<K, V> 只是显示为 AVLTree,因此得名“类型擦除”。

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

有人告诉我不要使用这个:

AVLTree<K extends Comparable<K>, V>

相反,他们说,使用这个:

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

但是,以下也可以:

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

我已经读过,如果您可以避免使用 SomeClass&lt;E&gt;,那么您应该避免使用这种语法,并且较新的 Java 正在使用这种语法 &lt;?&gt;. 有人可以澄清一下这对我的代码的区别和影响吗?如果我不一致,我是否可能会引入错误?

【问题讨论】:

  • 我会说K extends Comparable&lt;? super K&gt; 是正确的。 Object 是不必要的和暗示的(总是)。 Comaparble&lt;X&gt; 实际上不会为某些类编译(如果 Comparable 实际上是在 X 的超类上实现的)。但除此之外,您的问题非常广泛,可能应该分解成更小、更集中的问题。
  • 据我了解,某些方法(例如Collections.max())具有额外的Object &amp; 绑定的原因是因为(在Collections.max() 的情况下)这是此的预泛型版本方法有返回类型Object,并且他们需要方法的泛型版本具有相同的运行时签名,因此他们需要将T 擦除为Object 而不是Comparable。添加额外的Object 绑定首先会导致擦除为Object 而不是Comparable。可以说,pre-generics 版本应该返回 Comparable,但他们没有,所以他们坚持这样做。
  • 但除非您担心签名与您的库的先前版本的兼容性,或者类似的东西,否则我看不出您有任何理由添加多余的Object &amp; 绑定。
  • @newacct 这是一个很好的观点。考虑到这一点,我将省略它,因为我正在使用绝对需要擦除可比较的对象 - 例如 AVLTree、RedBlackTree,我需要在其中对值进行排序。谢谢

标签: java templates generics types


【解决方案1】:

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

声明AVLTree&lt;K extends Comparable&lt;? super K&gt;, V&gt; 意味着您可以通过父母(通过? super K)比较孩子。例如? extends CharSequence,您可以比较任何 CharSequence,而不仅仅是String。这些是the famous PECS 下的标准声明。

说实话,我很少需要这样做(可能是我没有经常公开我的 API),所以我通常这样做:

K extends Comparable<K>

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

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

【讨论】:

  • "所以我通常会这样做:K extends Comparable" K extends Comparable&lt;? super K&gt; 肯定更好。例如,假设您有一个类Animal,它与它自己相当(实现Comparable&lt;Animal&gt;)。而DogAnimal 的子类,你有一个Dogs 的列表。任何Dog 都可以与任何其他DogoneDog.compareTo(anotherDog)编译和工作)相媲美,但Dog 没有(也不能)实现Comparable&lt;Dog&gt;K extends Comparable&lt;K&gt; 绑定不适用于 Dog,但 K extends Comparable&lt;? super K&gt; 绑定可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多