深入学习 Java 语言的 `extends` 通配符!

举报
喵手 发表于 2025/03/19 18:15:46 2025/03/19
【摘要】 开篇语哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,...

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区: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 类型及其任何子类型的列表(如 IntegerDouble 等)。这种方式让方法更加灵活,可以接收多个不同类型的参数。

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 类型或者它的任意子类(如 IntegerDouble 等)。该方法通过 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 可以是 NumberObject 类型。

extends 通配符与实际应用

1. 通过 extends 实现灵活的集合操作

使用 extends 通配符可以在处理集合时,保持方法的通用性而不失去类型的约束。例如,处理不同类型的数字时,可以使用 List<? extends Number> 来传递 IntegerDouble 类型的列表,而不需要为每种类型写单独的处理方法。

2. 设计可扩展的 API

当设计需要支持多种类型参数的 API 时,使用 extends 通配符可以显著提高 API 的灵活性。例如,Spring 框架和其他库经常使用 extends 来实现对不同类型对象的支持,同时通过类型边界确保数据的一致性和安全性。

3. 与 Java 集合框架结合使用

泛型的 extends 通配符与 Java 的集合框架紧密结合。例如,当你需要从一个具有继承关系的类型中提取元素时,使用 List<? extends T> 来确保类型的安全。它适用于广泛的场景,如类型转换、排序等操作。

小结

  Java 中的 extends 通配符为泛型类型提供了强大的灵活性。它不仅使得类型限制更加清晰,还通过通配符支持了泛型方法和集合的广泛应用。通过正确使用 extends 通配符,可以在保证类型安全的前提下,使得代码更加灵活、通用,并且易于扩展。掌握 extends 通配符的使用,能够让你编写出更简洁、高效、可维护的 Java 代码。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。