aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes about adding object to List<? super X> Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "about adding object to List<? super X>" Watch "about adding object to List<? super X>" New topic
Author

about adding object to List<? super X>

Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451
Suppose we have Animal class and a Dog class that extends Animal class.

List <? super Dog> d = new ArrayList<Animal>();
d.add( new Dog()) //compiles.
d.add(new Animal()) // won't compile

List d can have a list of Animal, Dog and object based on <? super Dog> parameter.
It compiles to add Dog to it. But it won't compile to add Animal.

Why? (It may be out of the scope of the exam. But I am curious to know why.)
Tommy Delson
Ranch Hand

Joined: Apr 13, 2011
Posts: 206
In reference to K&B book "When you use the <? super ...> syntax, you are telling the compiler that you can accept the type on the right-hand side of super".

d.add(new Animal()) // won't compile

Problem: You cannot assign a Animal to <? super Dog>. The Animal is too "high" in the class hierarchy. Only <Dog> or <subtype> of Dog i.e Lasie, Wawa etc. would have been legal.
You cannot assign an Animal list to a reference that takes only a Dog (including any subtypes of Dog, of course).

Reread Chapter 7: Generics and Collections, page 619-622 to reinforce your knowledge and clear the concept.

Hope it help...


OCPJP6-05-11
"Your life is in your hands, to make of it what you choose."
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4363
    
    8

It's a common misunderstanding to think of List<? super Dog> meaning "a List that can accept any type of Dog or above". But that's not the case. What it really means is "a reference to a List of a specific type of Dog or above".

So it could be pointing at a List<Dog>, a List<Animal>, or a List<Object>. The compiler will only let you add to the list if it can guarantee that it's safe. That means it has to be an object that you could safely put into all these lists. Now, would you expect to be able to put an Animal into a List<Dog>?

And understanding this isn't out of scope, so it's worth getting straight!
Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451
Thanks for your reply.
List< ? super Dog> list can be assigned to new ArrayList<Animal> or ArrayList<Dog> or ArrayList<Object>.
Therefore,
case 1 : list = new ArrayList<Animal>();
case 2 : list = new ArrayList<Dog>();
case 3 : list = new ArrayList<Object>();

will all compiled.

However, when we attempt to add items to the list, only Dog object can be added.
The compiler is designed in this way, because it needs to prevent the programmers to add a Cat to list or any object like a String to the list as a Cat is not above Dog and a String is not above Dog.
Suppose,
case 1:
Animal cat = new Cat();
list.add(cat) , won't compile even though list is assigned to a list with Animal object inside it.

case 3:
Object o = new String();
list.add(o), won't compile even though list is assigned to a list with Object inside it.

Correct me if I am wrong.
Tommy Delson
Ranch Hand

Joined: Apr 13, 2011
Posts: 206
Seem like you haven't clear the concept, don't worry, it take sometime to clear it. I suggestion reread the Chapter many times until you fully understand each concept.

To address your last question, let me repeat once again "When you use the <? super ...> syntax, you are telling the compiler that you can accept the type on the right-hand side of super".

The point is on the statement above disregards Cat or String objects being add in the list, try to understand what it meant when you use "<? super ...>" syntax?

I let you decide and determine your question what's right or wrong....
Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451
Hi, when I read some another example,
List<? super Number> list = new ArrayList<Object> () ;
It compiles as Object is a super class of Number.
But if try to do this:
list.add(new Object()) ; //won't compile.
list.add(new Integer()); //compile
It is because the compile don't want you to add any object to the list. This object can be anything not related to Number.
But adding new Integer() or other subtypes of Number is fine.
The book says that sometimes it is ok to add to a list that is declare with <? super X>, where X is a class.

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18717
    
  40

Helen Ma wrote:case 1:
Animal cat = new Cat();
list.add(cat) , won't compile even though list is assigned to a list with Animal object inside it.

case 3:
Object o = new String();
list.add(o), won't compile even though list is assigned to a list with Object inside it.


I think it is better if you ignore that the possible cases exists. Remember that the compiler doesn't know the list as an ArrayList<Animal> or ArrayList<Object>. The list is type List<? super Dog>. The compiler doesn't know which of the three cases it is, after the assignment (okay, so the compiler is stupid).

As far as the compiler is concerned, it could be any of the three cases. This means that the code has to work for all three cases. If you want to add an object to the list, it has to be a type that IS-A Object, IS-A Animal, *and* IS-A Dog !! This behavior is not abitrary like "accept the type on the right-hand side of super", there is a reason for it.

Henry




Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Helen Ma
Ranch Hand

Joined: Nov 01, 2011
Posts: 451
Hi, Henry. I think the compile only let the list to add the type on the right hand side of the super.

List<? super Number> l = new ArrayList<Number>();
l.add(new Integer(1)) ; or l.add(new Double(1)); .... as they are the subtype of Number.

For l = new ArrayList<Object>() ; // compile
The compiler does not know what object will be in the list and prevent you from adding any object other than Number.

The compiler won't even let you add any object if
List<? extends Number> l = new ArrayList<Number>();
l.add( some object) ; //won't compile.
The compiler does not know what some object is . It can be Integer, Double.... It prevents you from adding a Double to Integer list.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: about adding object to List<? super X>