深入学习 Java 语言的 `extends` 通配符!
开篇语
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
在 Java 泛型(Generics)中,extends
通配符(Wildcard)是一个非常强大且灵活的工具,它能够帮助我们实现更加通用和可复用的代码。理解并正确使用 extends
通配符对于写出更优雅的泛型代码至关重要。在本文中,我们将深入探讨 Java 中的 extends
通配符,包括它的定义、用途、应用场景及其在实际编程中的最佳实践。
什么是 extends
通配符?
在 Java 泛型中,extends
通配符允许我们指定类型参数的上限(upper bound)。它表示我们可以传递一个类型或者该类型的子类型作为泛型参数。换句话说,extends
关键字可以让我们限制泛型类型只能是某个类的子类或实现了某个接口的类。
语法
class ClassName<T extends SomeClass> { ... }
T
必须是SomeClass
或者SomeClass
的子类。SomeClass
可能是一个类,也可能是一个接口。
上限与子类的关系
T extends SomeClass
:指定了T
类型必须是SomeClass
的子类(包括SomeClass
本身),但不能是SomeClass
的父类或其他不相关的类型。T extends SomeInterface
:指定T
类型必须实现某个接口(包括该接口本身),而不是其他不相关的类。
extends
通配符的应用
1. 使用 extends
通配符作为方法参数类型
extends
通配符常见的应用场景之一是作为方法参数类型的泛型限制。通过这种方式,可以传递指定类型及其子类型的对象作为参数。
示例 1: 传递子类型
public class WildcardDemo {
// 传递一个 Number 或其子类的对象
public static void printNumbers(List<? extends Number> list) {
for (Number number : list) {
System.out.println(number);
}
}
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3);
List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3);
// 传递 Integer 和 Double 的子类列表
printNumbers(integers); // Output: 1 2 3
printNumbers(doubles); // Output: 1.1 2.2 3.3
}
}
在这个例子中,printNumbers
方法的参数 List<? extends Number>
允许传递 Number
类型及其任何子类型的列表(如 Integer
、Double
等)。这种方式让方法更加灵活,可以接收多个不同类型的参数。
2. 限制返回类型的范围
extends
通配符不仅可以用于方法的参数,也可以用在返回类型上。比如,我们可以定义一个方法,使其返回某个类的子类或接口的实现类的对象。
示例 2: 返回子类型
public class WildcardDemo {
// 返回一个 Number 或其子类的对象
public static <T extends Number> T getFirstElement(List<T> list) {
return list.get(0);
}
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3);
List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3);
System.out.println(getFirstElement(integers)); // Output: 1
System.out.println(getFirstElement(doubles)); // Output: 1.1
}
}
在这个例子中,getFirstElement
方法返回一个 Number
类型或者它的子类类型。由于方法参数是泛型类型 T
,并且使用了 T extends Number
限制,这就保证了方法返回的对象一定是 Number
或其子类的实例。
3. extends
与通配符结合使用
extends
通配符常常与泛型集合一起使用,允许我们在集合中操作不同类型的对象,但保证这些对象满足一定的类型约束。例如,可以使用 List<? extends Number>
来表示一个列表,它可以包含 Number
或其任何子类型。
示例 3: 泛型集合中的 extends
通配符
public class WildcardDemo {
// 计算数字列表的总和
public static double sum(List<? extends Number> list) {
double sum = 0.0;
for (Number number : list) {
sum += number.doubleValue();
}
return sum;
}
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3);
List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3);
System.out.println(sum(integers)); // Output: 6.0
System.out.println(sum(doubles)); // Output: 6.6
}
}
在 sum
方法中,List<? extends Number>
表示传入的列表可以包含 Number
类型或者它的任意子类(如 Integer
、Double
等)。该方法通过 doubleValue()
方法来对每个数字进行求和。
4. extends
通配符与类型边界
如果你想要一个类的子类,或是实现了某个接口的类,你可以在泛型中使用 extends
进行限制。除了 extends
,你还可以使用 super
来限制下限,这使得类型参数必须是某个类或接口的超类。
示例 4: 限制类型的边界
public class WildcardDemo {
// 使用下限的通配符,可以接收 Number 或其超类类型
public static void addNumbers(List<? super Integer> list) {
list.add(10);
}
public static void main(String[] args) {
List<Number> numbers = new ArrayList<>();
addNumbers(numbers); // Number 或其超类类型可以添加 Integer
System.out.println(numbers); // Output: [10]
}
}
在上面的代码中,addNumbers
方法的参数类型是 List<? super Integer>
,这表示接受 Integer
或其超类类型的列表。这样,方法就可以将 Integer
对象添加到 List
中,甚至 List
可以是 Number
或 Object
类型。
extends
通配符与实际应用
1. 通过 extends
实现灵活的集合操作
使用 extends
通配符可以在处理集合时,保持方法的通用性而不失去类型的约束。例如,处理不同类型的数字时,可以使用 List<? extends Number>
来传递 Integer
或 Double
类型的列表,而不需要为每种类型写单独的处理方法。
2. 设计可扩展的 API
当设计需要支持多种类型参数的 API 时,使用 extends
通配符可以显著提高 API 的灵活性。例如,Spring 框架和其他库经常使用 extends
来实现对不同类型对象的支持,同时通过类型边界确保数据的一致性和安全性。
3. 与 Java 集合框架结合使用
泛型的 extends
通配符与 Java 的集合框架紧密结合。例如,当你需要从一个具有继承关系的类型中提取元素时,使用 List<? extends T>
来确保类型的安全。它适用于广泛的场景,如类型转换、排序等操作。
小结
Java 中的 extends
通配符为泛型类型提供了强大的灵活性。它不仅使得类型限制更加清晰,还通过通配符支持了泛型方法和集合的广泛应用。通过正确使用 extends
通配符,可以在保证类型安全的前提下,使得代码更加灵活、通用,并且易于扩展。掌握 extends
通配符的使用,能够让你编写出更简洁、高效、可维护的 Java 代码。
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
版权声明:本文由作者原创,转载请注明出处,谢谢支持!
- 点赞
- 收藏
- 关注作者
评论(0)