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

Eclipse与OpenJDK javac泛型通配符赋值行为差异及合规性疑问

问题描述

以下代码可在Eclipse 2022-12(4.26.0)中正常编译运行:

public static void main(String[] args) {
    List<List<?>> list = Arrays.asList(Arrays.asList("test"));
    System.out.println(test(list));
}

public static <T> T test(List<? extends List<T>> list) {
    return list.get(0).get(0);
}

但使用OpenJDK javac 19.0.2编译时会抛出编译错误:

error: method test in class Test cannot be applied to given types;
        System.out.println(test(list));
                           ^
  required: List<? extends List<T>>
  found:    List<List<?>>
  reason: cannot infer type-variable(s) T
    (argument mismatch; List<List<?>> cannot be converted to List<? extends List<T>>)
  where T is a type-variable:
    T extends Object declared in method <T>test(List<? extends List<T>>)

相关疑问:

  • 哪个编译器的行为是正确的?
  • 背后的原因是什么?
  • Java语言规范(JLS)中是否有明确规定该转换是否允许?
  • 补充实际场景:以下代码同样可在Eclipse中编译,但无法通过javac编译
ExecutorService executorService = /* ... */;
List<Callable<?>> callables = /* ... */;
executorService.invokeAll(callables);
解答
  1. javac的行为符合JLS规范,是正确的
  2. 核心原因:
    • 问题本质是泛型类型推断与子类型转换的规则冲突。调用test(list)时,编译器需要推断出一个确定的类型T,使得List<List<?>>可以安全转换为List<? extends List<T>>。
    • List<?>代表“元素类型未知的List”,而List<T>代表“元素类型为确定类型T的List”。List<?>并非List<T>的子类型——通配符?是一个不确定的类型占位符,而T是一个具体的类型变量,不存在任何确定的T能让List<?>成为List<T>的子类或超类。因此List<List<?>>无法满足List<? extends List<T>>的类型要求,因为前者的元素是“任意未知类型的List”,后者要求元素是“某个确定类型T的List的子类”,两者的类型边界不匹配。
    • Eclipse编译器做了超出规范的宽松处理,允许了不符合JLS的类型转换,而javac严格遵循了泛型的子类型规则。
  3. JLS的明确规定:
    根据JLS第4.10.2节《泛型类和接口的子类型》,对于泛型类型G<C1>和G<C2>,只有当C1在泛型子类型规则下是C2的子类型时,G<C1>才是G<C2>的子类型。由于List<?>和List<T>之间不存在合法的子类型关系,因此List<List<?>>无法转换为List<? extends List<T>>。
  4. 实际场景的解释:
    ExecutorService.invokeAll的方法签名为<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)。当传入List<Callable<?>>时,同样无法推断出确定的T让Callable<?>成为Callable<T>的子类型,因此javac拒绝编译,而Eclipse的宽松逻辑允许了该调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:25:33