• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Questions about generics.

 
Robbi Palacios
Ranch Hand
Posts: 96
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Fellow Ranchers,

1. Why won't the following method declarations work?

public <T super Dog> void takeAnimals(ArrayList<T> dogs) { }

public <? extends Animal> void takeAnimals(ArrayList<T> animals) {}

2. ( List <? extends Object> list ) and ( List<?> list)

Why can't you add anything to the list without super?

3. Based on the following code. Why can't you iterate through
dogs Arraylist?

public void takeAnimals( ArrayList<? super Dog> dogs) {
for( Dog d: dogs ) { d.makeNoise(); } // <-- This code block
//doesn't work. Why?
dogs.add(new Dog());
}

4. I noticed you can add in a list using <? super Dogs > and you
can't add using <? extends Animal>. You can iterate through a list by using <? extends Animal> while you cannot iterate through a list
using <? super Dog>.

Can someone explain to me why extends and super seem to work
inversely?

Thank you so much.
 
Keith Lynn
Ranch Hand
Posts: 2409
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Robbi Palacios:
Hi Fellow Ranchers,

1. Why won't the following method declarations work?

public <T super Dog> void takeAnimals(ArrayList<T> dogs) { }

public <? extends Animal> void takeAnimals(ArrayList<T> animals) {}


The purpose of the angle bracket is to define the type parameter you will use in the method. You can't use a wildcard there. You have to specify the type parameter. You are not allowed to use super with a type parameter, because the type that would be inferred would be Object and not any other superclass of the type parameter.

2. ( List <? extends Object> list ) and ( List<?> list)

Why can't you add anything to the list without super?


Could you be more specific about what you tried here?

3. Based on the following code. Why can't you iterate through
dogs Arraylist?

public void takeAnimals( ArrayList<? super Dog> dogs) {
for( Dog d: dogs ) { d.makeNoise(); } // <-- This code block
//doesn't work. Why?
dogs.add(new Dog());
}


Again the type inferred from ? super Dog is Object. So when the code is turned into bytecode, the type parameter will be replaced by Object.

4. I noticed you can add in a list using <? super Dogs > and you
can't add using <? extends Animal>. You can iterate through a list by using <? extends Animal> while you cannot iterate through a list
using <? super Dog>.

Can someone explain to me why extends and super seem to work
inversely?

Thank you so much.


Could you be more specific about the code you tried.

Notice that this declaration and code will compile and run with no problem.



but this will not



In the first case you are saying that the list can contain Dog or any of its superclasses so it is okay to add an instance of a Dog because that type is compatible with any of its superclasses.

However, in the second, the List can contain Dog or any of its subclasses. So adding a Dog won't work because a Dog object is not compatible with any of its subclasses.
 
Robbi Palacios
Ranch Hand
Posts: 96
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Keith, thanks dude that was some confusing generics.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic