返回
泛型世界的分叉小径:extends 与 super 的奥秘
java
2024-03-13 03:52:38
通往泛型之巅:探寻 extends 与 super 的边界
前言
在 Java 的广袤世界中,泛型宛如一柄利剑,赋予我们处理各种数据类型的神奇力量。但当我们深入泛型的迷雾时,extends 与 super 这两个关键词犹如两条分叉小径,让人彷徨。本文将带你踏上探索泛型边界的征途,拨开迷雾,揭开它们的神秘面纱。
上边界通配符:extends
extends 犹如一堵屏障,阻挡了超出指定类型及其子类的类型进入我们的泛型集合。换言之,List<? extends Number> 宣告:欢迎 Number 的家族成员,包括 Number 本人,但其他不相干的类型休想染指。
下边界通配符:super
与 extends 相反,super 则敞开大门,允许父类及其本身踏入泛型集合的领地。List<? super Number> 意味:Number 的祖先们,包括 Number,都是座上宾。
实战演练
让我们以一个真实的场景为例,在 removeNegatives 方法中,我们希望从一个泛型列表中剔除所有负数。代码如下:
void removeNegatives(List<? super Number> list) {
list.stream()
.filter(x -> x < 0) // 错误:不应移除所有负数
.forEach(System.out::println); // 错误:未返回或打印结果
}
然而,问题潜伏在暗处:
- 过滤器错误: x -> x < 0 过滤器将所有负数一网打尽,违背了方法的初衷。
- 打印错误: 代码返回一个流,却忘了将它转化为列表或打印到控制台。
修正方案
经过一番精雕细琢,我们修正了代码:
void removeNegatives(List<? super Number> list) {
list.stream()
.filter(x -> x.doubleValue() >= 0) // 使用 doubleValue() 转换为 double 以进行比较
.forEach(System.out::println);
}
现在,方法将正确过滤非负数并打印剩余元素。
结论
extends 与 super 是泛型世界的两块基石,掌握它们,才能在泛型之路上畅通无阻。牢记它们的用法:extends 筑起上边界,super 开启下边界。只要理解了它们的本质,你就能自信地驾驭泛型,书写优雅、高效的代码。
常见问题解答
-
extends 和 super 的区别是什么?
- extends:指定泛型类型必须是给定类型的子类或该类型本身。
- super:指定泛型类型必须是给定类型的父类或该类型本身。
-
什么时候使用 extends?
- 当你需要确保泛型类型只能包含给定类型及其子类时。
-
什么时候使用 super?
- 当你需要确保泛型类型可以包含给定类型的父类及其本身时。
-
使用泛型有哪些好处?
- 类型安全:防止不兼容类型进入泛型集合。
- 代码重用:减少重复代码,提高可维护性。
-
在使用泛型时应注意什么?
- 了解 extends 和 super 的区别。
- 仔细考虑泛型类型的边界。
- 避免不必要的泛型化,以免降低代码性能。