WildcardType 表示 Java 通配符类型,getUpperBounds() 恒返回非空数组(? 对应 {Object.class},? extends T 对应 {T}),getLowerBounds() 仅在 ? super X 时返回 {X},否则为空数组;二者互斥且长度均≤1。

WildcardType 是 Java 反射中表示通配符类型(如 ? extends Number 或 ? super String)的接口,它本身不直接实例化,而是由 JVM 在解析泛型签名时生成。要正确获取其上下界,关键在于理解它的语义规则和反射调用时机。
getUpperBounds() 返回的是“最具体的上界”
对于 ? extends T,getUpperBounds() 返回长度为 1 的数组,元素是 T;对于无界通配符 ?,它返回一个包含 Object.class 的数组(因为 ? 等价于 ? extends Object);对于多上界(如 ? extends A & B & C),只保留第一个(即 A),其余接口会出现在 getActualTypeArguments() 对应的 TypeVariable 或 Class 中 —— 但 WildcardType 本身不支持多上界语法,Java 语法也不允许 ? extends A & B,所以实际中不会出现多个上界。
- 示例:
List<? extends Runnable>→wc.getUpperBounds()[0]是Runnable.class - 示例:
Map<?, ?>→ 每个?的getUpperBounds()都返回{Object.class} - 注意:
getUpperBounds()永远不会返回空数组,至少是{Object.class}
getLowerBounds() 只在 ? super X 时非空
getLowerBounds() 返回的是下界类型数组,仅当通配符形如 ? super X 时才包含一个元素(即 X);其他情况(包括 ? 和 ? extends X)返回空数组 new Type[0]。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 示例:
Collection<? super Integer>→wc.getLowerBounds()[0]是Integer.class - 示例:
Function<? super String, ? extends Number>→ 第一个参数的 WildcardType 的getLowerBounds()非空,第二个的getUpperBounds()非空 - 不能同时有上界和下界:Java 语法禁止
? extends X super Y,所以两个方法返回结果互斥(要么上界有效,要么下界有效,或都默认)
如何安全地从 ParameterizedType 中提取 WildcardType
WildcardType 不会直接出现在字段/方法签名的顶层,而是嵌套在 ParameterizedType.getActualTypeArguments() 中。需先判断类型是否为 WildcardType 实例,再调用对应方法。
立即学习“Java免费学习笔记(深入)”;
- 不要强转:用
if (type instanceof WildcardType)判断 - 典型路径:
Field.getGenericType() → ParameterizedType → getActualTypeArguments() → 遍历每个 Type → 检查是否为 WildcardType - 示例代码片段:
Type[] args = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); for (Type arg : args) { if (arg instanceof WildcardType wc) { Type[] ups = wc.getUpperBounds(); // 总是非 null Type[] lows = wc.getLowerBounds(); // 可能长度为 0 // 处理 ups 或 lows } }
常见误区与注意事项
WildcardType 是运行时擦除后仍保留的泛型结构信息,但它不携带原始类或泛型实参的运行时类型 —— 所有边界类型也可能是 ParameterizedType 或 TypeVariable,需递归解析。
-
getUpperBounds()和getLowerBounds()返回的是Type数组,不是Class,可能包含泛型类型(如List<String>),不能直接强制转Class - 数组长度永远 ≤ 1:WildcardType 规范规定最多一个上界、一个下界
- 没有 “无界通配符的下界” 这种概念:
?的getLowerBounds()就是空数组,不是null - 反射无法还原源码写法:你无法区分
?和? extends Object,它们在运行时完全等价

















