After trying to understand the concepts at Spring MVC, I came across the expression Collection<? extends Book>
which I have never seen before. I have tried to figure it out on my own, but I am seeing no difference between using Collection<? extends Book>
and Collection<Book>
. I was guessing that it only allowed for extensions of Book, but it does allow for Book as well. So scratch that. I have tried using Google, but since ? is a wildcard in google, it makes it nearly impossible to search for. I have searched stackoverflow for the answer, but all questions about this (such as List<? extends MyType> and <? extends > Java syntax) already assume knowledge of Collection<? extends T>
. Here is the code that has initially intrigued my interest:
import java.util.ArrayList;
import java.util.Collection;
public class Book {
public static void main(String[] args) {
BookCase bookCase1 = new BookCase();
BookCase bookCase2 = new BookCase(bookCase1);
}
}
class BookCase extends ArrayList<Book> {
public BookCase() {
}
//acts same as public BookCase(Collection<Book> c) {
public BookCase(Collection<? extends Book> c) {
super(c);
}
}
What does <? extends T>
do? How does it differ from <T>
?
EDIT:
Followup question: Does BookCase extends ArrayList<Book>
mean that BookCase
extends Book
?
Consider the following
class Animal { }
class Horse extends Animal { }
private static void specific(List<Animal> param) { }
private static void wildcard(List<? extends Animal> param) { }
Without the extends syntax you can only use the exact class in the signature
specific(new ArrayList<Horse>()); // <== compiler error
With the wildcard extends you can allow any subclasses of Animal
wildcard(new ArrayList<Horse>()); // <== OK
It's generally better to use the ? extends syntax as it makes your code more reusable and future-proof.