Java的extends通配符

在Java泛型中,extends通配符用于限定泛型类型的上界,即指定泛型可以是某个类型或其子类型。它有两种常见用法:类型参数限定 和通配符限定,下面详细介绍:

1. 类型参数限定(在类/方法定义中)

在定义泛型类或方法时,使用extends关键字限制泛型类型必须是某个类(或接口)的子类。
语法 :<T extends 上限类型>

  • 示例1:限定泛型为Number的子类

    java 复制代码
    // 泛型类:T必须是Number或其子类(如Integer、Double)
    class GenericClass<T extends Number> {
        private T value;
        
        public GenericClass(T value) {
            this.value = value;
        }
        
        public double getDoubleValue() {
            return value.doubleValue(); // 可调用Number的方法
        }
    }
    
    // 使用:
    GenericClass<Integer> intClass = new GenericClass<>(10);  // 合法
    GenericClass<String> strClass = new GenericClass<>("abc");  // 编译错误(String不是Number子类)
  • 示例2:限定多个接口(用&分隔)

    java 复制代码
    // T必须同时实现Comparable和Serializable接口
    class MultiInterface<T extends Comparable<T> & Serializable> {
        // ...
    }

2. 通配符限定(在方法参数或变量声明中)

使用? extends 上限类型表示未知类型,但必须是指定类型的子类,常用于读取数据 (因为写入时类型不确定)。
语法 :? extends 上限类型

  • 示例1:方法参数中使用通配符

    java 复制代码
    // 只能处理Number或其子类的容器,且只能读取数据
    public static void printNumbers(Collection<? extends Number> nums) {
        for (Number num : nums) {
            System.out.println(num);
        }
        // nums.add(10);  // 编译错误:无法向通配符类型添加元素
    }
    
    // 使用:
    List<Integer> intList = Arrays.asList(1, 2, 3);
    printNumbers(intList);  // 合法
    List<String> strList = Arrays.asList("a", "b");
    printNumbers(strList);  // 编译错误(String不是Number子类)
  • 示例2:通配符与泛型类结合

    java 复制代码
    class Box<T> {
        private T value;
        // ... getter/setter
    }
    
    // 定义一个方法,接收"上限为Number"的Box,只能读取
    public static void processBox(Box<? extends Number> box) {
        Number num = box.getValue();  // 合法
        // box.setValue(10);  // 编译错误:无法确定具体类型
    }

3. extends通配符的核心规则

  • 只读原则 :? extends T类型的集合只能读取 元素(返回类型为T或其父类),不能写入 元素(因为无法确定具体类型)。
    例如:List<? extends Number>可以读取Number,但无法添加任何元素(包括Number本身)。
  • 类型传递性 :如果A是B的子类,List<A>是List<? extends B>的子类型。

4. 与super通配符的对比

  • extends通配符(? extends T):限定类型上限 (必须是T或其子类),用于读取。

  • super通配符(? super T):限定类型下限 (必须是T或其父类),用于写入 。
    示例 :

    java 复制代码
    // 写入场景用super:
    public static void addNumber(List<? super Integer> list, Integer num) {
        list.add(num);  // 合法,因为list元素类型至少是Integer的父类
    }

总结

extends通配符是Java泛型中实现类型安全 和灵活兼容的重要工具:

  • 定义泛型时,用<T extends 上限>限制类型范围,确保类型操作的合法性。
  • 使用泛型时,用? extends 上限允许接收子类类型,同时保证读取操作的安全(但牺牲写入能力)。
    合理使用通配符可以避免类型转换异常,提升代码的复用性和可维护性。
相关推荐
XIAEE8 分钟前
一个即时通讯项目是怎么长出来的:(Spring Boot 3 + Vue 3 微前端 + 悟空 IM + LiveKit)
java·spring
n876515 分钟前
Playwright Java WEB UI 自动化实现框架与逻辑
java·前端·ui
Java_AI工程师16 分钟前
Spring4 / SpringBoot1.x 老项目想接入 AI?不用升级框架!3 套无痛落地方案
java·人工智能·spring boot
BBmmo16 分钟前
Java Stream 的 filter 为什么看起来没运行?
java
VimorphTech21 分钟前
Java 文件缓存实战:如何避免读到未下载完成的视频?
java·spring boot
爱喝热水的呀哈喽31 分钟前
HEJIAN RESEARCH
开发语言·matlab
白露与泡影38 分钟前
后端 Java 面试核心八股汇总|高频面试题 + 解析,覆盖基础到进阶
java·开发语言·面试
xifangge20251 小时前
基于 JavaScript 实现 CNC 数控切削参数与螺纹公差纯前端核算引擎
开发语言·前端·javascript
“AI国潮设计-小江”1 小时前
【AIGC实战】Python+SDXL批量生成「潮汕英歌舞冰淇淋蛋糕&红桃粿咖啡」IP,固定角色形象批量出甜品商业效果图
开发语言·人工智能·python·prompt·aigc
SL_staff1 小时前
JVS-APS 实践:用双向反馈闭环打破制造计划孤岛
java·spring cloud·全栈