泛型方法中用类型参数承接通配符可绕过其限制,解决跨类型操作等问题;通过 process(List

在泛型方法中混合使用通配符与类型参数,核心不是“把它们写在一起”,而是通过类型参数承接通配符所代表的未知类型,从而绕过编译器对通配符的严格限制。这种组合能解决诸如跨类型集合操作、安全转换、只读/只写协调等典型不匹配问题。
用泛型方法封装通配符变量,实现类型“解包”
通配符(如 List extends Number>)本身不能直接参与泛型运算,但把它作为方法参数传入一个带类型参数 T 的泛型方法后,编译器可在该方法体内将通配符“捕获”为具体可推导的 T 或其子类型。
- 定义方法时让类型参数
T与通配符边界对齐:例如<t extends number> void process(List extends T> src)</t> - 此时
src.get(0)的类型被推为T,而非模糊的Capture#1 of ? extends Number - 你就能安全地把它传给需要
T的其他方法,或用于泛型容器创建
在参数位置嵌套通配符,放宽调用方约束
当方法要接收多种可能的函数式接口(如 Predicate、Function)时,单纯用 ? 会因无界导致推断失败;改用 ? super T 或 ? extends R 可激活协变/逆变适配。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 例如:
<t> List<t> filter(List<t> data, Predicate super T> p)</t></t></t> - 调用时传
Predicate<object></object>、Predicate<number></number>或Predicate<integer></integer>都合法 - 因为
? super T允许谓词处理T及其任意父类,既保证能接受T实例,又不限死实现细节
避免常见陷阱:通配符不参与类型推导链
通配符不能出现在方法返回值类型参数中参与推导(如 return (List extends T>) list),也不能和多个不同边界通配符混合作为同一类型参数的约束。
立即学习“Java免费学习笔记(深入)”;
- 错误写法:
<t> T convert(List extends T> src, List super T> dst)</t>—— 编译器无法统一两个通配符背后的隐式类型变量 - 正确做法:把其中一个通配符“升格”为方法的类型参数,另一个保持通配符,例如:
<t> void copy(List extends T> src, List<t> dst)</t></t> - 若需双向兼容,应拆分为两个独立泛型方法,或用辅助类封装上下界逻辑
实际场景:安全合并不同子类型的列表
假设你有 List<string></string> 和 List<integer></integer>,想统一转成 List<object></object> 并保持类型安全——不能强转,也不能丢泛型。
- 写一个泛型工具方法:
<t> List<object> toObjectList(List extends T> list)</object></t> - 内部用
list.forEach(obj -> result.add((Object) obj)),显式转为Object - 调用
toObjectList(strList)和toObjectList(intList)都通过编译,且无警告 - 比直接声明
List>更明确,比原始类型更安全

















