You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java嵌套泛型疑问:A<B<? super C>>与A<B<Object>>为何类型不匹配?

为什么A<B<? super C>>与A<B>无法兼容?

先看你提供的代码:

public class Main {
    public static void main(String[] args) {
        A<? super B> type1 = new A<Object>(); //编译正常
        A<B<? super C>> type2 = new A<B<Object>>(); //抛出类型不匹配错误
    }
}

class A<E> {}
class B<E> {}
class C {}

核心问题:泛型的「不变性」

Java里的泛型默认是不变的——意思是,就算X是Y的父类,G<X>和G<Y>之间也没有任何继承关系,不能直接互相赋值。比如List<String>和List<Object>,虽然String是Object的子类,但这两个List类型完全不兼容。

先解释第一个合法的例子

A<? super B> type1 = new A<Object>(); 能通过编译,是因为左边的A<? super B>是个通配符类型,它允许A的类型参数是B或者B的任意父类。右边的A<Object>用了Object作为类型参数,而Object确实是B的父类,完全符合? super B的要求,所以赋值合法。

再看报错的例子

左边是A<B<? super C>>,右边是A<B<Object>>,这里的关键是:

  1. B<Object>和B<? super C>这两个类型,虽然Object是C的父类,但因为B是不变的泛型类,所以B<Object>既不是B<? super C>的子类,也不是它的父类——它们是完全独立的类型。
  2. 而A同样是不变的泛型类,当它的两个类型参数(B<? super C>和B<Object>)没有继承关系时,A<B<? super C>>和A<B<Object>>自然也无法互相赋值,编译器就会抛出类型不匹配的错误。

怎么让赋值合法?

如果想让右边的A<B<Object>>能赋值给左边的变量,需要给左边的A也加上通配符,放宽类型约束,比如:

// 用通配符表示A的类型参数可以是B<? super C>的子类
A<? extends B<? super C>> type2 = new A<B<Object>>();

或者反过来,如果允许左边接受B<Object>的超类型,可以写成:

A<? super B<Object>> type2 = new A<B<Object>>();

但这两种写法都会损失一定的类型安全性,具体要根据你的业务需求选择。

内容的提问来源于stack exchange,提问作者Kcits970

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:10:03