0

Had seen many examples related to use of super wildcard. Majority of them are with Number and Integer classes. However for my understanding I was trying the below code:

package util;
import java.util.*;
class Animal{
    void eat() {
    System.out.println("animal eats");  
    }
}
class Dog extends Animal{
    void eat() {
        System.out.println("dog eats");
    }
}
class Cat extends Animal{
    void eat() {
        System.out.println("cat eats");
    }
}
public class Test {

    public void addAnimal(List<? super Dog> list) {
        list.add(new Animal());//******* getting error here
        list.add(new Dog());
    }
    public static void main(String[] args) {
    
    List<? super Dog> lsDogs = new ArrayList<Dog>();
    List<? super Dog> lsAnimals = new ArrayList<Animal>();
    
}
}

as per the docs which I have understood super means we can add anything that is on right hand side or its super class. Here I created Dog class which extends Animal class. I can only add Dog type of objects and not Animal. Why is it not possible.. any specific reasons

J. Doe
  • 69
  • 7
  • I write `public void addAnimal(List super Dog> list) {` as per docs super allows adding super class object. – J. Doe Mar 11 '22 at 10:55

2 Answers2

2

List<? super Dog> says "this is a List that you can add a Dog to. You might be able to add a Dog because it is a List<Dog>, because it's a List<Animal>, or because it's a List<Object>."

You can't add an Animal to a List<? super Dog>, because your Animal could be any Animal subclass, e.g. a Cat, and then you may have a Cat in a List<Dog>.

class Animal { void sound() {}}
class Cat extends Animal {}
class Dog extends Animal {}

class Test {
    public static void main(String[] args) {
        List<Object> objects = new ArrayList<>();
        List<Animal> animals = new ArrayList<>();
        List<Dog> dogs = new ArrayList<>();
        List<Cat> cats = new ArrayList<>();

        add(objects);
        add(animals);
        add(dogs);
        add(cats); // Error, must be a list we can add Dogs to

        addAnimal(objects);
        addAnimal(animals);
        addAnimal(dogs); // Error, must be a list which can contain any Animal
        
        useList(objects); // Error, must be a List of Animals
        useList(animals);
        useList(dogs);
        useList(cats);
    }

    public static void add(List<? super Dog> list) {
        list.add(new Dog());
    }

    public static void addAnimal(List<? super Animal> list) {
        list.add(new Dog());
        list.add(new Cat());
        for (Animal a : list) { // error, ? can be Object
            a.sound();
        }
    }
    
    // If we're consuming items from the list we use extends
    public static void useList(List<? extends Animal> list) {
        list.add(new Animal()); // error, ? is a specific but unknown subclass of Animal
        for (Animal a : list) {
            a.sound();
        }
    }
}
tgdavies
  • 10,307
  • 4
  • 35
  • 40
  • Ok so List super Dog> means it can accept either list of Dog, Animal or Object. But can add only Dog. If this is so.. then how do I traverse this wild card super list.. means If it accept List then what should be the reference type in for loop – J. Doe Mar 11 '22 at 11:31
  • I'm not sure what for loop you mean, in which context. Please edit your question. – tgdavies Mar 11 '22 at 11:33
  • I've added an example using a loop, might be what you're after? – tgdavies Mar 11 '22 at 11:39
0

The ? means that we don't know what the class is but it is a definite class.

? super of Dog means that ? is something that is a parent of dog. For your example you have { Object, Animal, Dog }. So your ? can be any of those 3 classes.

You can add to the list as long as what every you add can be cast to ?.

Can you add a Dog to the list? Yes because Dog can be cast to any Object, Animal, Dog.

Can you add an Animal to the list? No, because Animal cannot be cast to Dog.

Since Dog is the most specified it is the boundary that we compare against. You can add any Dog or class that extends Dog.

matt
  • 10,892
  • 3
  • 22
  • 34