Search code examples
javagenericslower-boundupperbound

Questions about the upper bound of generic in java


please see the following code:

import java.util.ArrayList;

public class Animal{...}
public class Dog{...}

public class TestAnimal{
    
    public static void killAll(ArrayList <T extends Animal> animals){
        System.out.println("animals are dead");
    }

    public static void main(String[] args){
        ArrayList<Animal> simonAnimal = new ArrayList<>();
        ArrayList<Dog> simonDog = new ArrayList<>();
        
        killAll(simonAnimal);
        killAll(simonDog);  
    }
}

the line that causes the problem is:

public static void killAll(ArrayList <T extends Animal> animals){

so what I want to do is to be able to use killAll() method on the any ArrayList that contains objects that are the sub class of Animal, in this case - the Dog class. I don't know what's wrong with my code. please help!

the error message is: Incorrect number of arguments for type ArrayList; it cannot be parameterized with arguments <T, Animal>

I just replaced

<T extends Animal>

as

<? extends Animal>

it works, but can someone tell me why doesn't work?


Solution

  • You're trying to declare a type variable T and its bounds, and you're trying to use it all at once, which you can't do in Java generics. I don't get that error message; I get "unexpected bound".

    First, declare the type variable and its bounds, in angle brackets before the return type, and refer to it as the type argument to the method parameter. This will remove the compiler error.

    public static <T extends Animal> void killAll(ArrayList<T> animals) { ... }
    

    But we can do better. First, program to the interface and use List<T>. Also, if you aren't using the specific type of T in the actual body, then you can use an upper-bounded wildcard instead of an explicit type variable.

    public static void killAll(List<? extends Animal> animals) { ... }