超全模态模型 × Harness 升级,升级解锁 ArkClaw,最新支持 DeepSeek-V4 系列与 GLM-5.1
先看你提供的代码:
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类型完全不兼容。
G<X>
G<Y>
List<String>
List<Object>
A<? super B> type1 = new A<Object>(); 能通过编译,是因为左边的A<? super B>是个通配符类型,它允许A的类型参数是B或者B的任意父类。右边的A<Object>用了Object作为类型参数,而Object确实是B的父类,完全符合? super B的要求,所以赋值合法。
A<? super B> type1 = new A<Object>();
A<? super B>
A
B
A<Object>
Object
? super B
左边是A<B<? super C>>,右边是A<B<Object>>,这里的关键是:
A<B<? super C>>
A<B<Object>>
B<Object>
B<? super C>
C
如果想让右边的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
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起
模型再升级,30秒超长叙事, 模态参考扩容
模型自由,工具不限,最新支持 Deepseek-V4 系列、GLM-5.3 系列
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列
大模型19元起,Al应用9.9元畅享,新人首购爆款尽享优惠