应按pecs原则选择通配符:输出用? extends t保障读取安全,输入用? super t放宽写入范围;如logall(list

关键在于按用途选对通配符边界:输入用 ? super T 放宽接纳范围,输出用 ? extends T 保障读取安全。不是接口定义里硬写通配符,而是在方法参数或返回类型中动态应用。
输入参数用 ? super T:让接口能接收更宽泛的容器
当方法要往集合里写数据,就用下界通配符。它允许传入 T 或其任意父类的集合,只要能存下 T 就行。
- 比如日志批量写入:
void logAll(List super String> targets, List<string> logs)</string>,传ArrayList<object></object>、ArrayList<charsequence></charsequence>都合法 - 可以安全调用
targets.add("msg"),因为所有目标集合都承诺能装下 String - 但读取时只能得到
Object,不能直接转成String—— 这是设计换来的写入自由
输出结果用 ? extends T:让调用方拿到可安全使用的值
当方法返回一个只读集合,就用上界通配符。它保证所有元素都是 T 或其子类,调用方能按 T 安全使用。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 比如统一读取数字:
List extends Number> getNumbers(),返回ArrayList<integer></integer>或ArrayList<double></double>都行 - 调用方能遍历并调用
doubleValue(),因为每个元素都继承自Number - 但不能往这个集合里 add 任何东西(除了 null),编译器禁止——这是为读取安全做的限制
组合场景用嵌套通配符:比如 Predicate super T>
当接口本身是泛型函数式接口,把它作为参数传入时,常配合通配符提升兼容性。
- 例如过滤方法:
<t> List<t> filter(List<t> data, Predicate super T> p)</t></t></t> - 传入
Predicate<object></object>或Predicate<charsequence></charsequence>都可以处理String列表 - 因为谓词只要能处理 T 或它的父类,逻辑上就足够判断 T 的行为,且不会越界
牢记 PECS 原则,别反着用
Producer Extends,Consumer Super —— 看集合是“产出”还是“消费”数据来决定边界方向。
- 集合用来往外给数据(如返回值、foreach 源)→ 用
? extends T - 集合用来往里塞数据(如方法参数、add 目标)→ 用
? super T - 混用场景(如 copy(src, dst)):src 用
? extends T,dst 用? super T,刚好匹配
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










