I will show you two style of declaration of generics. In part1, I'm using generic upper boundary declaration on List as follows:
List<? extends Animal> totList = new ArrayList<Animal>();
But this will throw error like below if you try to add a Animal object to the list:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method add(capture#1-of ? extends Animal) in the type List<capture#1-of ? extends Animal> is not applicable for the arguments (Animal)
at GenericsType.main(GenericsType.java:39)
But as in Part2, if I declare the list inside a generic class in the format below, no errors are thrown while adding (Animal objects) or (subclass of Animal objects) to the list.
class GenericAnimal<T extends Animal>
{
List<T> genList = new ArrayList<T>();
}
Why in part2, it didn't throw error and what is the difference between two style of declaration.
Example Code:
1.Animal.java
public class Animal {
private String name;
private int height;
public void animalJump()
{
if(height>100)
{
System.out.println(name+" with height-"+height+" can JUMP");
}
else
System.out.println(name+" with height-"+height+" cannot jump");
}
public void setName(String name) {
this.name = name;
}
public void setHeight(int height) {
this.height = height;
}
public Animal(String name, int height) {
setName(name);
setHeight(height);
}
}
2.GenericsType.java
import java.util.*;
import Animal;
import Animal.Cannine;
import Animal.Feline;
import Animal.Feline.Cat;
import Animal.Cannine.Dog;
public class GenericsType {
public static List<? extends Animal> totList = new ArrayList<Animal>();
public static void processAllfunc1()
{
for(Animal a : totList)
{
a.animalJump();
}
}
public static void main(String args[])
{
// Part 1
totList.add(new Animal("Animal1",21)); // Error: Unresolved compilation problem:
processAllfunc1();
// Part 2
GenericAnimal<Animal> genericanimal = new GenericAnimal<Animal>();
genericanimal.genList.add(new Animal("Animal2",22)); // No Error, why?
genericanimal.genList.add(new Cat("Cat4",204)); // No Error for Cat also, why?
genericanimal.processAllfunc2();
}
}
3.GenericAnimal.java
public class GenericAnimal<T extends Animal> {
public List<T> genList = new ArrayList<T>();
public void processAllfunc2() {
for (T a : genList) {
a.animalJump();
}
}
}
In part 2, the type of genericanimal.genList
is List<T>
= List<Animal>
. In part 1, the type of the list is List<? extends Animal>
List<? extends Animal>
.
The issue is that List<? extends Animal>
List<? extends Animal>
means "a list of some specific subtype of Animal which is unknown." For example, you could write List<? extends Animal> list = new ArrayList<Cat>()
List<? extends Animal> list = new ArrayList<Cat>()
. And you shouldn't be able to add any animal to a list of cats. By writing List<? extends Animal>
List<? extends Animal>
, you're saying that you want to deliberately lose track of which type of animal is allowed into the list, though you know that whatever's in the list is some type of animal.
Why in part1, it threw error while trying to add an Animal object to the list?
List<? extends Animal> totList = new ArrayList<Animal>();
totList.add(new Animal("Animal1",21)); // Error: Unresolved compilation problem:
Because compiler restricts addition of objects on list declared using upper bounded wildcard( ? extends Animal). Compiler doesnt know for sure if the list is typed to the Animal, or Cat or Dog.
Simple, whenever a variable is declared using Upper bounded Wildcard, then inserting elements is not allowed to that variable.
Advantages of using Upper bounded Wildcard is that:
Why in part2, it didn't throw error while adding an Animal object and also Cat object to the list?
public List<T> genList = new ArrayList<T>();
genericanimal.genList.add(new Animal("Animal2",22)); // No Error, why?
genericanimal.genList.add(new Cat("Cat4",204));
Because Here genList is actually of type Animal like in below format
List<Animal> genList = new ArrayList<Animal>();
Now just like normal list of specific type, it can add elements of that type.
So an Animal object can be added to List Also Cat object is allowed to be added since it is also an Animal object only (Cat is just a subclass of Animal)
Advantages of using <T extends Animal>
is that:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.