In generics as we know we can not assign subclass generic type to super class generic type, for example
List<animal> list = new ArrayList<dog>();
will not compile even though Dog IS-AN Animal. the reason for this is already explained in generics basics section.
How can we solve this particular problem?????
we can solve this problem by using wildcard in generics, which is denoted by ?. to solve above problem we need to use the wildcard like below.
List<? extends Animal> list = new ArrayList<dog>(); ? extends Animal means we can assign any List to the reference list provided it is of Animal type or subclass of animal type. List<? extends Animal> list = new ArrayList<dog>(); List<? extends Animal> list = new ArrayList<cat>(); List<? extends Animal> list = new ArrayList<animal>();
also read:
all above three lines will compile provided Cat IS-A N Animal and DOG IS-AN Animal.but we can not add anything to the list, the reference has to be used to call methods so that we can get polymorphic behavior.
public class Generics { @SuppressWarnings("unchecked") public static void main(String[] args) { List<dog> list1 = new ArrayList<dog>(); list1.add(new Dog()); iterateAnimals(list1); } private static void iterateAnimals(List<? extends Animal> list){ //list.add(new Dog()); for(Animal animal : list ){ System.out.println(animal.toString()); } list.add(null); } } class Animal{ public String toString() { return "Animal"; } } class Dog extends Animal{ public String toString() { return "Dog"; } }
above code produces Dog as output. as we can see in the iterateAnimals() method body, we are not allowed to add anything to the list except null. only value allowed to add is null if we use ? extends syntax.