1

Some days ago I was writing a simple Java program, and I discovered that this piece of code doesn't work (it gives a compile-time error):

ArrayList<Document> docs = new ArrayList<Book>();

where Document is an interface and Book implements Document.

Why inheritance in Java doesn't work with generics? If I want that code to work, I must use wildcards, like this:

ArrayList<? extends Document> docs = new ArrayList<Book>();

I was wondering what is the reason of this? If I need an ArrayList of Documents, and I know that a Book is also a Document, why can't I use an ArrayList of Books as an ArrayList of Documents?

2

2 Answers 2

7

consider the following example:

ArrayList<Book>books = new ArrayList<Book>();
ArrayList<Document> docs = new ArrayList<Book>();
docs.add(new Document());
Book book = books.get(0); //Oops, now we have a variable of type book, referring to a Document that is not a book. Not good.

If you want more conceptual background material about this issue read up on Covariance and Contravariance

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, I didn't know that if I use <? extends MyType> I can not add elements, but only read them.
5

It's just because the type of List<U> can't be a type a subtype of List<V> (unless U = V).

enter image description here

If you admit for example that List<Integer> is a subtype of List<Number>. You could write the following :

void addPi(List<Number> l) {
 l.add(3.14);
}

List<Integer> l = new LinkedList<>();
addPi(l);

What is the problem here ?

1 Comment

Thank you very much, I didn't think that there could be problems when adding new items.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.