下界通配符(? super t)不适合过滤,因其仅允许写入、禁止安全读取元素类型;过滤应使用具体类型或上界通配符(? extends t),配合predicate实现类型判断与筛选。

Apache Commons Collections 本身不直接支持 Java 泛型的下界通配符(? super T)来做“集合元素过滤”——因为过滤操作关注的是**读取并判断元素是否符合条件**,而下界通配符主要用于**向集合写入(添加)更宽类型的元素**,二者语义相反。
简单说:用 Collection super Number> 是为了能往里加 Integer、Double 等;但你要“过滤出所有 Integer”,就得能安全地 读取 元素并检查类型,这时需要的是上界(? extends Number)或具体类型,而不是下界。
为什么下界通配符不适合过滤?
下界通配符(? super T)表示“某个未知的父类型”,编译器只允许你:
- 向集合中添加
T或其子类实例(如add(Integer)); - 但不允许安全地读取元素——因为你不知道取出的是什么类型(可能是
Object,甚至更宽的类型),无法做类型判断或 cast。
例如:Collection super Integer> coll = new ArrayList<number>();</number>
你不能写 coll.iterator().next() instanceof Integer —— 编译器会报错或只能得到 Object,失去类型信息。
实际过滤该怎么做?推荐方式
用 Commons Collections 过滤集合,应基于已知具体类型或上界通配符,配合 Predicate。常见做法:
-
用具体泛型类型(最清晰):
Collection<number></number>→ 可安全遍历、instanceof 判断、cast; -
用上界通配符(读安全):
Collection extends Number>→ 可读出Number或其子类,适合判断和过滤; - 避免在过滤逻辑里用下界通配符参数——它不是为“读+判”设计的。
示例:用 Commons Collections 4.x 过滤 Number 集合中的 Integer
假设你有一个 Collection<number></number>,想留下所有 Integer:
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
Collection<number> numbers = Arrays.asList(1, 2.5, 3, 4.0, 5);
Collection<number> integers = CollectionUtils.select(numbers, new Predicate<number>() {
@Override
public boolean evaluate(Number n) {
return n instanceof Integer;
}
});
// integers 包含 [1, 3, 5]
</number></number></number>
如果你传入的是 Collection extends Number>,一样可用(因为可读出 Number):
Collection extends Number> input = numbers; Collection<number> result = CollectionUtils.select(input, n -> n instanceof Integer); </number>
如果非要“带下界”参与流程?注意角色分离
下界通配符可在输入接收或结果收集阶段出现,但过滤逻辑本身仍需具体/上界类型:
- 比如方法签名接受
Collection super Integer> target,表示“可把 Integer 往里加”; - 但你真正过滤的源集合仍是
Collection<number></number>或Collection extends Number>; - 过滤完再把结果 addAll 到那个
target中——这时下界才起作用。
这不是“用下界做过滤”,而是“用下界接收过滤结果”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











