function

Java 中 Function super T, ? extends R> 的签名,不是随意设计的,而是 PECS 原则在函数抽象层面的精准落地——它把“参数可放宽、返回可收窄”推到了逻辑极值。
参数用 ? super T:消费端极致兼容
函数接收的不是“必须是 T”,而是“能装下 T 就行”。只要类型是 T 或其父类(比如 T 是 Integer,Number 或 Object 都合法),就能安全传入。编译器不关心你实际传的是什么父类,只确保 T 可以无损向上转型。
- 一个
Function<number string></number>能处理List<integer></integer>的 map 操作,因为Integer→Number安全 - 写死
Function<integer string></integer>就卡死了——哪怕逻辑完全通用,也无法复用已有的Number→String函数 - 这正是“消费者(Consumer)用 super”的本质:输入越抽象,适配面越广
返回用 ? extends R:产出端极致精确
函数返回的不是“只能是 R”,而是“只要是 R 或其子类就 OK”。调用方拿到结果后,总能安全地当 R 用;而实现方却可以返回更具体的类型(比如 R 是 Number,返回 BigDecimal 或 AtomicInteger 都没问题)。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
Optional<integer>.map(x -> new BigDecimal(x))</integer>能顺利编译,因为BigDecimal是Number的子类 - 若限定死返回
Number,你就得手动包装、舍弃子类语义,徒增冗余 - 这正是“生产者(Producer)用 extends”的核心:输出越具体,信息越丰富,调用越灵活
合起来看:不是妥协,而是双向强化
这个泛型签名同时达成两件事:
- 输入侧放开边界——让已有函数能被更多场景复用(宽进)
- 输出侧保留精度——让返回值仍具实际类型意义(窄出)
- 全程不牺牲类型安全:不会把
String当Integer用,也不会往List<integer></integer>里塞Double
Stream.map、Optional.map、RxJava 的 transform 等所有标准转换操作都采用这一模式,因为它在泛型表达力和运行时安全性之间找到了最紧致的平衡点。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










