Java泛型<? super 接口>参数传入ArrayList报编译错误问题
下界通配符
<? super T>在T为接口时的匹配规则 问题场景
当方法参数定义为ArrayList<? super T> list且T为接口类型时,对可传入的ArrayList泛型类型存在疑问,相关复现代码如下:
基础类型定义
public interface Fruits {} public interface SweetFruitsInterface extends Fruits{} public class FruitParty <T extends Fruits> { public void getFruits(ArrayList<? super SweetFruitsInterface> fruitList) { System.out.println("Lets get Fruit List"); } }
测试类定义
public class SweetProducts {} public class SweetFruits extends SweetProducts implements SweetFruitsInterface{}
报错调用代码
ArrayList<SweetProducts> sweetProductsArrayList1 = new ArrayList<>(); fruitsFruitParty.getFruits(sweetProductsArrayList1);
以上代码触发编译错误,核心疑问点:
SweetProducts属于SweetFruitsInterface实现类的父类,为什么无法通过编译?- T为接口时,下界通配符的实际匹配逻辑是什么?
解答
核心规则澄清
Java泛型的下界通配符? super T匹配规则和T是类还是接口没有任何区别:仅允许传入泛型参数为T本身、或T的直接/间接父类型的集合,匹配逻辑只校验集合声明的泛型类型和T的直接继承关系,和T的实现类、子类自身的继承链无关。
在本案例中,方法参数要求匹配? super SweetFruitsInterface,因此仅三类泛型的ArrayList是合法入参:
SweetFruitsInterface本身SweetFruitsInterface的直接父接口Fruits- 所有引用类型的公共父类
Object
报错原因
SweetProducts确实是SweetFruitsInterface实现类SweetFruits的父类,但SweetProducts本身没有实现SweetFruitsInterface,和SweetFruitsInterface不存在继承/实现关系,不属于SweetFruitsInterface的父类型,因此传入ArrayList<SweetProducts>不符合通配符边界要求,必然触发编译错误。
注意不要混淆两个概念:
- T的父类型:指T直接/间接继承、实现的类型,是通配符
? super T的合法匹配范围 - T的子类/实现类的父类型:属于子类自己的继承链,和T本身没有直接继承关系,不在匹配范围内
合法传参示例
以下调用均可正常通过编译:
FruitParty fruitsFruitParty = new FruitParty(); // 传入SweetFruitsInterface本身类型的集合 ArrayList<SweetFruitsInterface> sweetFruitList = new ArrayList<>(); fruitsFruitParty.getFruits(sweetFruitList); // 传入父接口Fruits类型的集合 ArrayList<Fruits> fruitList = new ArrayList<>(); fruitsFruitParty.getFruits(fruitList); // 传入公共父类Object类型的集合 ArrayList<Object> objectList = new ArrayList<>(); fruitsFruitParty.getFruits(objectList);
内容的提问来源于stack exchange,提问作者ayushpratap32
相关产品推荐
相关产品推荐

