方法参数为接口类型List,传入实现该接口的泛型类List为何不生效?
问题原因
你遇到的编译报错本质是Java泛型的不变性特性导致的:
虽然你通过泛型约束定义了C extends FooInterface,说明C本身是FooInterface的子类型,但List<C>和List<FooInterface>之间不存在继承关系,Java泛型默认是不变的,不支持自动向上转型。
举个反例说明为什么Java要设计成不变:假设编译器允许把
List<C>传入List<FooInterface>类型的参数,那么在testMethod内部就可以合法地往List里插入任意实现FooInterface的其他类对象,比如另一个实现类Bar implements FooInterface,这就会破坏原List<C>只能存放C类型对象的类型约束,运行时会出现类型转换异常,所以编译器直接在编译阶段拦截了这种操作。
解决方案
方案1(推荐):修改工具类方法的参数为协变泛型
将testMethod的参数声明为List<? extends FooInterface>,即可接收所有元素为FooInterface子类型的List:
public class Utils { public void testMethod(List<? extends FooInterface> list){ // 该方法内只能读取list元素(自动向上转型为FooInterface),不能插入非null元素 } }
方案2:强制类型转换(仅适合确定工具方法不会修改List内容的场景)
如果不能修改工具类的方法定义,可以通过两次转型完成传参,不过该操作有类型安全风险,不推荐优先使用:
public TestClass(){ Utils.testMethod((List<FooInterface>)(List<?>) lists); }
内容的提问来源于stack exchange,提问作者Loading
相关产品推荐
相关产品推荐

