• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

about adding object to List<? super X>

 
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.)
 
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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...
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 206
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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



 
Helen Ma
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
reply
    Bookmark Topic Watch Topic
  • New Topic