• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Generics - ? super Animal

 
Prem Vinodh
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear All,

I am having a problem with understanding Generics and I have tried this sample program. The source of the program is SCJP 5 By Kathy Sierra & Bert Bates.

Please refer to the program below :

--------------------------------------------------------------------------
import java.util.*;

class SuperAnimal
{
String sname = null;

public String getSname() {
return sname;
}

public void setSname(String sname) {
this.sname = sname;
}
}

class Animal extends SuperAnimal
{
public void addAnimal(List <? super Animal> animals) {
//animals.add(new SuperAnimal()); // 1
animals.add(new Animal());
animals.add(new Dog());

for(int iCnt = 0; iCnt < animals.size(); iCnt++) {
System.out.println("Animals["+iCnt+"] ::"+animals.get(iCnt));
}
}
}

class Dog extends Animal
{
String name = null;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

public class GenericsSuper
{
public static void main(String[] args) {
Animal animal = new Animal();

List<? super Animal> animal1 = new ArrayList<SuperAnimal>();
animal1.add(new Dog());
animal1.add(new Animal());
//animal1.add(new SuperAnimal()); // 2
animal.addAnimal(animal1);

List<? super Animal> animal2 = new ArrayList<Animal>();
animal2.add(new Dog());
animal2.add(new Animal());
//animal2.add(new SuperAnimal()); // 3
animal.addAnimal(animal2);

//List<? super Animal> animal3 = new ArrayList<Dog>();

List<? super Animal> animal4 = new ArrayList<Object>();
//animal4.add(new Object()); // 4
animal.addAnimal(animal4);

}
}
---------------------------------------------------------------------------

Q1) Why can't I add a SuperAnimal Object at // 1? The list says <? super Animal> so I thought it should and moveover it is accepting a Dog object which is a subclass of Animal which it should not? Similary for // 2 and // 3.

Q2) Refer the line just above // 4 which is this
List<? super Animal> animal4 = new ArrayList<Object>();
which means it can take an object (because Object is parent to all other classes and my addAnimal method takes superclass of Animal) so when I trying to add an object to the list it shows error. why?

Thanks in advance.
 
Henry Wong
author
Marshal
Pie
Posts: 20881
75
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Q1) Why can't I add a SuperAnimal Object at // 1? The list says <? super Animal> so I thought it should and moveover it is accepting a Dog object which is a subclass of Animal which it should not? Similary for // 2 and // 3.


You have to think about it a different way, basically <? super Animal> means that the compiler doesn't know what the list holds, but it is an object that is a super class of type animal.

Animal works because by default, an Animal IS-A super of type Animal. Dog works because a sub class of Animal IS-A Animal, which IS-A super of type Animal.

It is *not* necessary true that a super of Animal IS-A another super of Animal. And since the compiler doesn't know which super of Animal is supposed to be in the list, it can't allow the operation.

Q2) Refer the line just above // 4 which is this
List<? super Animal> animal4 = new ArrayList<Object>();
which means it can take an object (because Object is parent to all other classes and my addAnimal method takes superclass of Animal) so when I trying to add an object to the list it shows error. why?


This is basically the same question as the first one. Keep in mind that the reference is a <? super Animal> type, so the compiler is assuming that it doesn't know what super it is. The same explaination (as the first question) applies here.

Henry
 
Prem Vinodh
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Henry. I now understand.
But for the exam how do I handle cases similar to this.
Is it that I apply the same logic.

Because frankly speaking I am struggling to get a hold on Generics
and I was planning to take the SCJP by mid June. And still I am struggling to understand it. But your explanation is fine and I understood that.

Thanks a lot.
 
Shivani Yadav
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am also confused...Can anybody please tell me the difference between <? extends Dog> and <? super Dog>



from the above code should i say that
<? extends Dog> and <? super Dog> both can accept same kind of Objects i.e those satisfying the (IS-A Dog ) condition only that when we are using <? extends Dog> we cannot modify the list while in <? super Dog> we can modify the list.
Please correct me if my understanding is incorrect.

Thanks,
 
Ankit Garg
Sheriff
Posts: 9509
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shivani Jadhav wrote:
from the above code should i say that
<? extends Dog> and <? super Dog> both can accept same kind of Objects i.e those satisfying the (IS-A Dog ) condition only that when we are using <? extends Dog> we cannot modify the list while in <? super Dog> we can modify the list.


You are yourself saying that you cannot add any elements to <? extends Dog>, then how is it similar to <? super Dog>. The thing is, when you say List<? super Dog>, then you know that the List is of a super type of Dog, so you are sure that you can add elements of type Dog (and sub-classes of Dog) to it. But while retrieving from such a list, you don't know the actual type of objects the list might be holding so you can take out elements only into references of type Object (unless you use a cast of course). In case of List<? extends Dog>, you actually don't know what is the actual type of the elements in the List. Suppose Dog class has 2 sub-classes, BullDog and Pomeranians, then the List can be of any of these types. Since you don't know the actual type, you can't add elements to it. But whatever the type is, it is surely a sub-type of Dog (or Dog itself), so you can get elements out of it into references of type Dog.

Read the FAQ for more details. And also please create a new thread for your questions. This thread is more than a year old...
 
Prem Vinodh
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

Sorry for the late reply.
I have posted this question and taken my certification the following week.
After I cleared the certification I did not come back to look at these posts so I did not click on the stop watching the post.
Sorry for my lousiness and a very very big THANKS for all the good effort. For your'll helped me understand some of the hardest
topics without your kind help I wonder where and how I would have got the concepts right.

Thanks for all the good work.
Please accept my sincere apologies for my lousiness (I am a bit ashamed too for my lousiness)
Hope all of your'll will excuse me.

Thanks
Prem Vinodh
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic