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

为何List<Integer>的forEach可接受非Integer父类型的Consumer?

问题解析:为什么List的forEach可以传入操作String的Lambda

先拆解清楚核心逻辑,你误解的点在于把Lambda内部的操作类型和Consumer的参数类型混为一谈了:

  1. forEach的泛型约束本质
    对于List<Integer>,它的forEach方法签名是void forEach(Consumer<? super Integer> action)——这里要求的是:这个Consumer能接受Integer或者它的任意父类型的参数。注意,是Consumer的输入参数类型要满足? super Integer,和Consumer内部做什么操作完全无关。

  2. 你的Lambda实际对应的类型
    看这段代码:

ints.forEach(x -> {
    if (x != null) nonNullStrings.add(x.toString());
});

这里的x是Integer类型(因为ints是List<Integer>,forEach遍历的元素都是Integer),所以这个Lambda对应的是Consumer<Integer>。而Integer本身就属于? super Integer的范畴(Java里一个类型自己也是自己的超类型),完全符合forEach的泛型要求。

  1. 纠正你的误解
    你误以为Lambda内部操作了String就需要Consumer<String>,但实际上Lambda的参数类型由forEach的上下文(也就是List的元素类型)决定,和Lambda内部生成的String无关。这个Lambda只是把每个Integer转成String再添加到另一个List,它本身还是接受Integer作为输入的Consumer,完全满足约束条件。

对比下面strings.forEach的代码,它的Lambda是Consumer<String>,符合List<String>的forEach要求的Consumer<? super String>,逻辑是完全一致的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:57:10