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

Java中A<B<? extends Integer>>赋值给A<B<?>>为何编译通过?

class A<T> {
}

class B<T extends Integer> {
}

public class Main {
    public static void main(String[] args) {
        A<B<?>> a1 = null;
        A<B<? extends Integer>> a2 = null;
    
        a1 = a2;
    }    
}

问题

我认为在此程序中,a1的类型并非a2类型的超类型,且捕获转换对两者的类型均为恒等转换。我认为a1 = a2;属于转换链,根据JLS 5.2规定:

若转换链中包含两个无父子类型关系(§4.10)的参数化类型,会触发编译错误。

但编译器未报错或警告,为何该赋值操作被允许?


解答

这是因为B<?>和B<? extends Integer>在当前场景下本质是等价类型,进而A<B<?>>和A<B<? extends Integer>>具备合法的子类型关系,符合赋值转换规则。

具体来说,泛型类B的类型参数被声明为T extends Integer,这意味着B的所有参数化类型,其类型参数的上限都被固定为Integer。此时B<?>中的通配符?会被隐式限定为? extends Integer——通配符无法突破类定义时设定的类型参数上限。因此B<?>和B<? extends Integer>是完全等价的参数化类型,它们的捕获转换结果也一致:都会生成以新类型变量(上限为Integer)为参数的B类型。

对于泛型类A<T>,既然B<? extends Integer>与B<?>等价,那么A<B<? extends Integer>>可被视为A<B<?>>的子类型(甚至可认为两者本质是同一类型),因此a1 = a2的赋值操作完全符合JLS规则,不会触发编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:59:52