我使用泛型完成了什么?

What am I accomplishing using generics?

我有以下代码块:

public static void main(String[] args) {
    Integer[] test = new Integer[100];
    comparableTest(test);
    genericsTest(test);
}

private static void comparableTest(Comparable[] c) {

}

private static <E extends Comparable<E>> void genericsTest(E[] e) { }

我使用泛型究竟完成了什么?这些都没有编译错误。我仍然可以使用 compareTo 方法。那么我使用 E extends Comparable<E> 而不是仅使用 Comparable 有什么好处呢?

这个问题的上下文是我正在使排序算法使用 E extends Comparable<E> 而不是 Comparable

说明

  • 如果没有泛型,您可能会得到一个 class,它不能与自身相比较,而是与其他事物相比较。就像 A implements Comparable<B>,这很不寻常但有可能。

  • 此外,您只是在 compareTo 上失去了类型安全性,因为它会退回到接受 Object。所以你可能会不小心犯错,传递错误的东西 Java 无法帮助你防止它。

实际上,如果您没有被迫为 Java 之前的版本开发,那么您没有理由考虑使用 原始类型 (放弃泛型) 5.


例子

例如,考虑到您的代码段,您将 Integer[] 传递给它。 Integer 无法与 Dog 进行比较。所以如果你不小心做了一些愚蠢的事情,比如:

Dog dog = new Dog();
if (c[0].compareTo(dog) == 0) { ... }

这实际上将使用采用 Comparable[] 的变体进行编译,但在您执行它时会在运行时崩溃。另一个变体能够在编译时检测到这个错误,通常可以帮助您更早地发现错误,这很好。

这个例子可能看起来做作,但这样的事情可能很快就会发生。


备注

您可能需要考虑将 c 重命名为有助于提高可读性的名称。阅读 c 的人可能不知道它在您的情况下代表什么,也许它代表一个角色,也许代表一辆汽车。

一般来说,尽量避免缩写。 comparableselementsitems.

呢?