0

I am currently reading about wildcards but I cant figure out if there is any difference between ? extends Animal and E extends Animal.

The Squake
  • 13
  • 3

2 Answers2

0

? extends Animal is used for when you're trying to say that any class that extends Animal is okay as input. For example, List<? extends Animal>. You would use E if you wanted to keep track of the object type in the class as you write the code. You might want just a single type through the object.

public class Node<T, E extends Animal> {
    public T findByObj(E obj) {
        // return index in Integer
    }
}

In this case, you would instantiate and use it like this:

Node<Integer, Person> node = new Node<Integer, Person>();
node.findByObj(new Person());

You might be expecting something from the Person class, but a random class could be used. It keeps the type safe and the behavior is predictable.

nohnce
  • 61
  • 5
0

Wow my head almost exploded thinking about this... From my understanding these both do the same thing. Maybe they do this in somewhat different contexts though? For example class definitions, method declarations, or return types from methods. Please see some code I wrote to illustrate this. Hopefully, someone more knowledgeable will type a reply but I wanted to try to answer this.

So basically...

? is a wildcard that says any sub-type of the Animal class or the Animal class itself.

Please read this on wildcards in generics: https://en.wikipedia.org/wiki/Generics_in_Java

Here is some more info on bounded types which the <E extends Animal> example you gave apparently is: https://docs.oracle.com/javase/tutorial/java/generics/bounded.html

This says any object that IS-A Animal or an Animal object itself is acceptable for this class or method argument.

Try typing out some code and experiment with different objects inside the Animal hierarchy and outside to see differences. For example make a LolCat class that extends Animal. Check out my program as follows:

import java.util.ArrayList;
import java.util.List;

class Animal {

 public String toString() { 
    return "I am an animal!";
 }

}

class LolCat extends Animal {

  public String toString() { 
    return "I am a lolcat!";
  }


}

class Machine{}

class Computer extends Machine {}

public class TestThis{

    public <U extends Animal> void anyAnimal(U u) {
        System.out.println("This is an animal ");
        System.out.println(u);
        System.out.println("The object type of U is: " + u.getClass().getName());

    }

    public void listAnimalFriends(List<? extends Animal> a) {

        System.out.println("This is in the animal list: ");
        for (Animal anima: a) {
            System.out.println(anima);
        }


    }



    public static void main(String[] args) {

        TestThis t = new TestThis();
        t.anyAnimal(new LolCat());

        System.out.println("\n");

        ArrayList<Animal> a_list = new ArrayList<>();
        a_list.add(new LolCat());

        t.listAnimalFriends(a_list);


    }

}
user3808269
  • 1,321
  • 3
  • 21
  • 40