【从零开始学Java | 第二十四篇】泛型的继承和通配符

目录

前言

一、泛型的继承

二、泛型的通配符

总结


前言

在上一篇博客中,我们认识了泛型,它会帮我们在编译器就拦截了类型转换异常。但是当泛型遇到继承呢?既然 Integer 继承自 Number,那 List<Integer> 是不是 List<Number> 的子类?

答案是否定的,接下来对这一知识点进行详细说明。

一、泛型的继承

泛型不具备继承性,但是数据具备继承性。

为什么Java不允许List<Animal> list = new ArrayList<Dog>()这样操作呢?

如果这行代码编译通过了,animalList表面是一个可以装所有动物的集合。那是不是说明一个继承自Animal类的Cat类也能存入animalList中。但是,animalList实际上是ArrayList<Dog>,等你想把它当狗拿出来的时候,程序就会崩溃。

数据具备继承性:

java 复制代码
public class GenericsTest01 {
    public static void main(String[] args) {
        List<Animal> animalList = new ArrayList<>();
        animalList.add(new Animal());
        animalList.add(new Dog());
        
    }
}

class Animal {}
class Dog extends Animal {}

二、泛型的通配符

现在有这样一个场景,需要定义一个方法,形参是一个集合,但是集合中的数据类型不确定,应该怎么做?

一般方法,使用泛型方法

java 复制代码
public class GenericsTest02 {
    public static void main(String[] args) {
        
    }
    
    public static <E> void method(ArrayList<E> list){
        
    }
}

存在缺陷,利用泛型方法此时它可以接收任意的数据类型

java 复制代码
public class GenericsTest02 {
    public static void main(String[] args) {
        ArrayList<Animal> al1 = new ArrayList<>();
        ArrayList<Dog> al2 = new ArrayList<>();
        ArrayList<Student> al3 = new ArrayList<>();
        method(al1);
        method(al2);
        //这也是对的
        method(al3);
    }

    public static <E> void method(ArrayList<E> list){

    }
}

class Animal {}
class Dog extends Animal {}

class Student {}

但是我们通常希望,尽可能传递Animal类及其子类,此时就引出了泛型的通配符:

上限限制<? extends T>表示:泛型类型必须是 T 本身,或者是 T子类

下限限制:<? super T>表示:泛型类型必须是 T 本身,或者是 T父类

此时上述修改后的方法为:

此时传递Student类时方法就会报错,但是传递Dog就不会。

泛型的通配符:可以限定类型的范围。

应用场景:

1.如果我们在定义类、方法、接口时,如果类型不确定,就可以定义泛型类、泛型方法、泛型接口。

2.如果类型不确定,但是能知道以后只能传递某个继承体系中的类,就可以使用泛型的通配符。

总结

  • 泛型无继承: List<Dog> 不是 List<Animal>

  • <?> 无界通配符,能接万物,但只能读不能写。

  • <? extends T> 规定了上限。安全地(取出 T)。

  • <? super T> 规定了下限。安全地(存入 T 的子类)。

相关推荐
SimonKing16 分钟前
OpenCode 桌面版这 10 天偷偷迭代了 5 个版本,你还在用旧版吗?
java·后端·程序员
小大宇39 分钟前
python sqlalchemy 案例
开发语言·python
Dontla1 小时前
冒烟测试介绍(Smoke Test、BVT构建验证测试、构建验收测试)与回归测试对比、与单元测试对比、与集成测试对比、Cypress
java·单元测试·集成测试
名字还没想好☜1 小时前
Go 结构体内存对齐:调整字段顺序,同样的字段省下 40% 内存
开发语言·后端·golang·go·内存对齐
暖和_白开水1 小时前
数据分析agent(十):loguru日志输出优化 和es 启动流程
java·elasticsearch·数据分析
减瓦1 小时前
Gradle 版本演进全景:构建工具的进化密码
java·gradle
玛丽莲茼蒿1 小时前
很难出错的Spring5(十)—— IOC进阶
java·开发语言·jvm
Ulyanov1 小时前
雷达导引头仿真中的坐标系——从惯性系到量测角
开发语言·python·算法·系统仿真·雷达信号处理·雷达导引头
减瓦1 小时前
Jackson 使用指南
java·spring boot·json
Devin~Y1 小时前
互联网大厂 Java 面试实录:Spring Boot、MyBatis、Redis、Kafka、Spring Security、RAG 与 MCP 全链路问答
java·redis·kafka·mybatis·spring security·spring mvc·sprint boot