• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

SCJP Generics Question

 
Krishna Attravanam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
public class GenericEx2 {

public static void add(List<? super GRetriever>l, Dog d){
l.add(0,d);//1
}

public static void main(String[] args) {
List<? super GRetriever> list = new ArrayList<Dog>();//2
add(list,new GRetriever());//3
}
}

class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
class GRetriever extends Dog{}

Why does the compiler complain about line 1?
I am unable to come up with a proper explanation for this behavior.

Line 1: Creates a List which can have GRetriever or any super class of it
Line 2: Passing an instance of GRetriever
Line 3: Adding Dog-referenced GRetriever() to the list.

Thanks
Krishna
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"Krishna,"

Welcome to JavaRanch!

Please revise your display name to meet the JavaRanch Naming Policy. To maintain the friendly atmosphere here at the ranch, we like folks to use real (or at least real-looking) names, with a first and a last name.

You can edit your name here.

Thank you for your prompt attention, and enjoy the ranch!

-Marc
 
Deepak Bala
Bartender
Posts: 6663
5
Firefox Browser Linux MyEclipse IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
List<? super GRetriever> list; what this means is that you can instantiate any object that is a GRetriever or above on the right hand side of the defenition , which you have done by using a < Dog >. However you will only be able to add objects that are GRetrievers or its subclasses. Consider this...


when you add an Animal() BANG !
 
Jay Ashar
Ranch Hand
Posts: 208
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is the text I got from generics tutorial from Sun, hope this helps

"The type of the second parameter to shapes.add() is ? extends Shape - an unknown subtype of Shape. Since we don�t know what type it is, we don�t know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn�t safe to pass a
Rectangle there."
 
Arno Reper
Ranch Hand
Posts: 286
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I try to compile I got :
"cannot find symbol : method add(int,dog)
location : interface java.util.List<capture of ? super GRetriever>"
I don't understand...could you reexplain plz?
thanks
arno
[ April 06, 2006: Message edited by: Arno Reper ]
 
Krishna Attravanam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks John!..One more question based on your answer

I modified the previous question a bit.

package examples;
import java.util.*;

public class GenericEx2 {

public static void add(List<? super GRetriever> list){ //1
//list can add GRetriver or any subclass of it -- right?
list.add(new GRetriever()); //2
printAll(list);
}

public static void printAll(List<GRetriever> list){ //3

public static void main(String[] args) {
List<Dog> list = new ArrayList<Dog>();
list.add(new GShepherd()); // Adding a Germal Shepherd
list.add(new GRetriever());

}

}

class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
class GRetriever extends Dog{}
class GShepherd extends Dog{}

Now line 1 says list can add a GRetriever or a subclass of it. When I pass the list as an argument to printAll method compilation fails at 3. Is it because I need to replace the definition to List<? super GRetriever> ?

How do I then print all the objects in the list ? I tried this but didnt work

for(Animal animal : list){
System.out.println(animal);
}

I think I am not able to understand wildcard behaviour somewhere
Can someone explain
Thanks
Krishna
 
Arno Reper
Ranch Hand
Posts: 286
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ps : you forgot one bracket at line 3...
 
Krishna Attravanam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oops sorry ... That should nt matter though ... It still doesnt compile <g>
 
Arno Reper
Ranch Hand
Posts: 286
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
=> => => => => =>
=> i understand now
Ouf...lol
 
Arno Reper
Ranch Hand
Posts: 286
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Its the fact you use List<GRetriever> in your printall method, a List<? super GRetriever> could be a List<Dog> whats not a List<GRetriever>.
It look like
List<Parent> = List<Children> //compiler error ... you see?
damn I hate those generics...lol
[ April 06, 2006: Message edited by: Arno Reper ]
 
Krishna Attravanam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Assuming we replace List<GRetriever> with List<? super GRetriever>, the compiler doesnt complain. Now I cant use this in printAll method

for(Animal o: list){
System.out.println(o);
}

for(Dog o: list){
System.out.println(o);
}

The only line which works is

for(Object o: list){

}

Why is that?
Now I am lost

Krishna
 
Arno Reper
Ranch Hand
Posts: 286
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ouch...
hummm, I would say : List<? super GRetriever> could contain things that are higher than GRetriever and the highest class is Object...
Its just a guess...
 
Changchun Wang
Ranch Hand
Posts: 83
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
let us discuss the get and put rule about List <? super GRetriever> list
when we put a element into list,we must assure the element which you do is the type of GRetriever or the type of GRetriever's subclasses.
but when we get a element form the list ,we don't know which type about it ,only it is Object(because all class extends Object implicitly)
so only the following is correct
list.add (new GRetriever());
for (Object o :List){System.out.println(o);}

but the get and put rule about List <? extends Animal> list2 is different from it

list2.add(null);// only do this
for (Animal a:list2)//of course Object can in the place of Animal
{System.out.println(" "+a);
}
 
Changchun Wang
Ranch Hand
Posts: 83
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

maybe you should undersand subtype among the collections
List <Animal> is subtype of List<? extends Animal>
that a another way to do it
List<? extends Animal> o1
List <Animal> o2
o1=o2;

List<? super GRetriever > is subtype of List<? super T > which T is the type of GRetriever or GRetriever's sublcass

you can get more from jls
changchun!
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
SECOND WARNING. You ignored the one request above. Please change it now, or your account will be suspended.

"Krishna"

Please click on the My Profile link above and change your display name to match the JavaRanch Naming Policy of using your real first and real last names.

Thanks

Mark
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic