• Post Reply Bookmark Topic Watch Topic
  • New Topic

Wildcard with List  RSS feed

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I have this piece of code:


I don't understand why I can't add a Dog to the ArrayList because I have already specified the type the ArrayList should take in line 1 already : new ArrayList<Dog>();

Thank you for your help.
 
Ranch Hand
Posts: 1163
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the ranch Huy Huy. Do you understand how generics work? Do you understand what it means when you say :

?

What is the "?" for?

Yes, Dog IS-A Object, i.e. Dog extends Object. But don't think an ArrayList<Dog> IS-A List<? extends Object>. Though the wildcard ? gives you flexibility for declaring the parametrized types, you still aren't allowed to add anything, except for a null. Otherwise, as Campbell rightly pointed out, you may end up adding a Cat, Rat or may be even an Integer to the list that is supposed to be type safe for a Dog. Inheritance applies only to base types not parametrized types. If you have :

and



You can't write : . And even if you write , you do not have the liberty to add anything to the list except a Dog type.
 
Marshal
Posts: 56610
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Go through the Java Tutorials and look for generics with ctrl-F. It should appear twice. Yo will probably find that a List<? extends Object> might ba a List<Dog>, but it could just as easily be a List<Cat>. If you allow that, you would be able to add a Cat to it. So you cannot (I think) add anything to a List<?...>
You could try List<T extends Object> but that is only slightly better than a List<Object>.
 
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Huy huy wrote:I don't understand why I can't add a Dog to the ArrayList because I have already specified the type the ArrayList should take in line 1 already : new ArrayList<Dog>();

Yes, but generics is not like inheritance or overriding, which are dealt with by the JVM at runtime; it is a compile-time syntax only.

Simply put: you can't modify a collection defined with a wildcard, and it's the compiler that stops you, not the JVM.

I suspect that part of the reason for your confusion is that you are declaring and modifying it in the same code, so it's obvious to you that myArrayList is an ArrayList<Dog>, but it's NOT obvious to the compiler. After all, you could just as easily have defined it as:

List<? extends Object> myArrayList = new ArrayList<String>();

Suppose you passed myArrayList to a method in some other class defined in a completely different package. Would you expect to be able to pass it to a method defined as:
public void doSomethingWithList(ArrayList<Dog> list) { ...
?
Well, whether you did or not, the fact is: you can't.

You can, however, pass it to a method defined as:
public void doSomethingWithList(ArrayList<? extends Object> list) { ...
but then the question becomes:
Do you think you should still be able to add a Dog inside that method?

Maybe the easiest way to remember it is this: '?' in generics means "unknown". That doesn't mean that the List doesn't have a type, simply that the compiler doesn't know what it is; so how could it possibly allow you to add a Dog?

HIH

Winston
 
Huy Than
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you very much for all of your reply and enthusiasm in helping me. I have read your answers twice and read this one http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html

However, I still have 2 more questions to bother you. That is:

Question 1:
Given:


if I understand correctly, the parameter in ArrayList<>() must be Object, so do we need to write it? Or we just skip it like this:



Question 2:
Given:

as I understand, the left side of "=" means myArray is a reference of List type, which can be List<Cat> or List<Dog>, ....
What about the right side of "=", what does it mean? Does it mean that the reference myArray is assigned to an real object of List which contains only Dog? If yes, I can't not think about a situation when the information in the right side of "=" is useful or necessary. Can you give me an example where
is essential or at least useful.

Thank you for your valuable time.

  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!