Recently, I read this article:
http://download.oracle.com/javase/tutorial/extra/generics/wildcards.html
My question is, instead of creating a method like this:
public void drawAll(List<? extends Shape> shapes){
for (Shape s: shapes) {
s.draw(this);
}
}
I can create a method like this, and it works fine:
public <T extends Shape> void drawAll(List<T> shapes){
for (Shape s: shapes) {
s.draw(this);
}
}
Which way should I use? Is wildcard useful in this case?
It depends on what you need to do. You need to use the bounded type parameter if you wanted to do something like this:
Here we have a
List<T> shapesand aT shape, therefore we can safelyshapes.add(shape). If it was declaredList<? extends Shape>, you can NOT safelyaddto it (because you may have aList<Square>and aCircle).So by giving a name to a bounded type parameter, we have the option to use it elsewhere in our generic method. This information is not always required, of course, so if you don’t need to know that much about the type (e.g. your
drawAll), then just wildcard is sufficient.Even if you’re not referring to the bounded type parameter again, a bounded type parameter is still required if you have multiple bounds. Here’s a quote from Angelika Langer’s Java Generics FAQs
Quotes from Effective Java 2nd Edition, Item 28: Use bounded wildcards to increase API flexibility:
Applying the PECS principle, we can now go back to our
addIfPrettyexample and make it more flexible by writing the following:Now we can
addIfPretty, say, aCircle, to aList<Object>. This is obviously typesafe, and yet our original declaration was not flexible enough to allow it.Related questions
<? super T>mean and when should it be used and how this construction should cooperate with<T>and<? extends T>?Summary