Home > OS >  Questions about the upper bound of generic in java
Questions about the upper bound of generic in java

Time:01-18

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?

CodePudding user response:

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) { ... }

CodePudding user response:

The correct syntax for declaring a type variable on a method looks like this:

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

CodePudding user response:

I know it might seem unintuitive, but even though Dog is a subtype of Animal, ArrayList is not a subtype of ArrayList. As pointed out by others, you can use a wildcard type.

ArrayList<? extends Animal> denotes any generic ArrayList type whose type parameter is a subclass of Animal such as ArrayList.

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

It is also better to use a List instead of a concrete implementation like ArrayList

CodePudding user response:

The correct way to make generic methods like your example is this:

public static <T extends Animal> void killAll(List<T extends Animal> animals){#code}

As other colleagues told you, it is better to receive a list than an arraylist.

  • Related