我一直使用java Generics和现有的集合API,并且知道它提供编译时类型安全性。
但我对在我的类中使用通配符或有界类型参数感到困惑。当编译器类型Erasure实际上用基类型替换它时,有人可以澄清使用这些的优点。为什么我们不应该将代码引导到基类
作为java教程(http://docs.oracle.com/javase/tutorial/java/generics/genMethods.html)
的一个例子您可以编写一个通用方法来绘制不同的形状:
public static <T extends Shape> void draw(T shape) { /* ... */ }
Java编译器将T替换为Shape:
public static void draw(Shape shape) { /* ... */ }
那么为什么我们不应该直接写入Shape参数,使用通配符或有界类型有什么好处呢?
答案 0 :(得分:2)
在你的例子中,绝对没有任何好处。
考虑以下方法签名
public static <T extends Shape> void draw(List<T> shapes) { /* ... */ }
我可以做以下
final List<Circle> circles = /* ... */
final List<Square> squares = /* ... */
draw(squares);
draw(circles);
我无法做到
public static void draw(List<Shape> shapes) { /* ... */ }
这对于PECS类型的情况尤为重要。
答案 1 :(得分:0)
使用泛型代码是类型安全的,并且您的集合是类型安全的。这意味着将在编译时捕获更多问题,而不是运行时。
没有泛型,
ArrayList将是object类型的ArrayList,这意味着您可以在其中放置任何内容。
泛型允许您确保在ArrayList中放置的任何内容都是特定类型。例如,如果要创建ArrayList,则只能放入Cars对象而不能放入其他任何对象。
只是一个占位符,无论你想要什么。如果你的程序只想创建一个汽车的ArrayList并且从不创建不同的类型,你可以在整个程序中轻松使用占位符而不是E.
问题是,能够在所有不同类型的对象上创建不同的类型并执行不同的操作非常重要,因此创建ArrayList的类通常是E用于&#39;元素&#39;然后在其他类中,您将创建特定类型。
为您的问题&gt;&gt;&gt;&gt;查看此链接Java: bounded wildcards or bounded type parameter?