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

为何编译器允许将Pair<String,String>对象添加至Pair<String,Integer>列表?

为什么直接在add方法中创建错误泛型的Pair实例能通过编译?

我用Pair类存储体育场名称和容量信息,遇到了泛型检查的疑问:

  • 第一个示例(符合预期):创建List<Pair<String, Integer>>类型的列表后,显式声明Pair<String, String>变量并尝试添加,编译器报错,符合预期。
  • 第二个示例(存在疑问):直接在add方法内创建Pair<String, String>实例并添加,编译器未报错,程序可编译执行。

第一个示例(符合预期)

List<Pair<String, Integer>> stadiums = new ArrayList<>();
stadiums.add(new Pair("Bridgeforth Stadium", 25000));
stadiums.add(new Pair("Michigan Stadium", 109901));

Pair<String, String> stringPair = new Pair("Lane Stadium", "some str value");
stadiums.add(stringPair); // 编译错误:Required type:Pair<String,Integer> Provided:Pair<String,String>

第二个示例(存在疑问)

List<Pair<String, Integer>> stadiums = new ArrayList<>();
stadiums.add(new Pair("Bridgeforth Stadium", 25000));
stadiums.add(new Pair("Michigan Stadium", 109901));

stadiums.add(new Pair("Lane Stadium", "some str value")); // 无编译错误

原因解析

这是Java泛型的类型推断与原始类型特性共同作用的结果:

  1. 第一个示例的报错逻辑:
    你显式声明了Pair<String, String>类型的变量stringPair,其泛型类型被明确固定。当传递给stadiums.add()时,编译器能直接对比变量类型与列表要求的Pair<String, Integer>,发现类型不匹配,因此抛出编译错误。

  2. 第二个示例的无报错逻辑:
    直接写new Pair("Lane Stadium", "some str value")时,未指定泛型参数,创建的是原始类型的Pair实例。Java的原始类型会绕过泛型检查(源于泛型擦除机制),编译器会将其视为兼容任意泛型参数的Pair,因此add方法不会触发编译错误。

⚠️ 注意:这种写法虽然能编译,但后续如果对列表中的该元素做类型相关操作(比如把getValue()的结果当作Integer处理),运行时会抛出ClassCastException。如果想让编译器在第二个示例中也报错,只需显式指定泛型参数:new Pair<String, String>("Lane Stadium", "some str value"),此时编译器就能检测到类型不匹配并报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 02:12:43