请看下面的代码:
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);
}
}
引起问题的行是:
public static void killAll(ArrayList <T extends Animal> animals){
所以我想做的是能够使用killAll()方法在任何数组列表中包含的对象是动物的子类,在这种情况下-狗类。我不知道我的代码出了什么问题。请帮助!
错误信息是:类型ArrayList的参数数量不正确;它不能用参数
来参数化我只是替换了
& lt; ?扩展Animal>
它工作,但谁能告诉我为什么不工作?
您正在尝试声明类型变量T
及其边界,并且您正在尝试一次使用它,这在Java泛型中是无法做到的。我没有看到错误信息;我得到了"意外边界"。
首先,在返回类型前的尖括号中声明类型变量及其边界,并将其作为方法形参的类型实参引用。这将删除编译器错误。
public static <T extends Animal> void killAll(ArrayList<T> animals) { ... }
但是我们可以做得更好。首先,对接口进行编程,使用List<T>
。另外,如果您没有在实际正文中使用T
的特定类型,那么您可以使用上界通配符而不是显式类型变量。
public static void killAll(List<? extends Animal> animals) { ... }
在方法上声明类型变量的正确语法如下:
public static <T extends Animal> void killAll(ArrayList<T> animals){
System.out.println("animals are dead");
}
我知道这可能看起来不太直观,但是即使Dog是Animal的子类型,ArrayList也不是ArrayList的子类型。正如其他人指出的,您可以使用通配符类型。
ArrayList
public static void killAll(List <? extends Animal> animals){
最好使用List而不是像ArrayList
这样的具体实现。创建类似示例的泛型方法的正确方法是:
public static <T extends Animal> void killAll(List<T extends Animal> animals){#code}
正如其他同事告诉你的那样,接收一个列表比接收一个数组列表要好。