Java泛型中<T super Animal>无效的原因及正确写法咨询
Java泛型
super关键字的编译错误原因及正确用法 为什么<T super Animal>会编译失败?
Java泛型语法明确规定:super关键字不能用于泛型方法的类型参数声明(也就是<>里的类型参数约束)。只有extends可以用来定义类型参数的上界,而super仅能用于**通配符(?)**的下界约束。
简单说,<T super Animal>这种写法本身就不符合语法规则——泛型类型参数需要一个明确的、可限定的类型范围,而super Animal表示“所有Animal的父类”,这个范围是无限向上延伸到Object的,无法作为类型参数的有效约束。
super的正确使用场景
super的核心作用是在通配符中指定下界,对应PECS原则里的“Consumer Super”(消费者用Super),也就是当你需要向一个容器/方法参数中写入元素时,用? super X来确保容器能容纳X及其子类的实例。
正确写法示例1:接收Animal及其父类的方法
如果你的superDemo需要处理Animal或它的父类对象,应该用通配符代替类型参数:
static void superDemo(? super Animal obj) { // 合法操作:可以将Animal或其子类实例赋值给obj obj = new Animal(); obj = new Dog(); // 也可以赋值为FatherOfAllAnimal实例,因为它是Animal的父类 obj = new FatherOfAllAnimal(); }
正确写法示例2:向集合写入元素的典型场景
这是super最常用的场景,确保集合可以接收目标类型及其子类:
static void addAnimalInstances(List<? super Animal> animalList) { animalList.add(new Animal()); animalList.add(new Dog()); animalList.add(new Cat()); } // 调用示例 public static void main(String[] args) { // 可以传入Animal的List List<Animal> animals = new ArrayList<>(); addAnimalInstances(animals); // 也可以传入Animal父类的List List<FatherOfAllAnimal> allAnimals = new ArrayList<>(); addAnimalInstances(allAnimals); }
总结
- 泛型方法的类型参数声明(
<T>)只能用extends指定上界,不能用super super仅能搭配通配符?使用,用于指定下界,服务于“写入”操作的场景- 你的
superDemo方法如果需要处理Animal及其父类,改用通配符? super Animal作为参数类型即可解决编译问题
内容的提问来源于stack exchange,提问作者CuriousMind
相关产品推荐
相关产品推荐

