泛型知识笔记

Java泛型完整笔记

一、泛型基础

泛型:参数化类型,把类型作为参数。

  • 作用:编译期做类型检查,避免强制类型转换,防止ClassCastException
  • 特点:只在编译期生效,运行时做类型擦除,字节码中泛型信息消失。

常用占位符:

  • T Type 类型
  • E Element 元素
  • K Key 键
  • V Value 值
  • ? 通配符

1.泛型类

语法:public class 类名<T> {}

java 复制代码
public class Result<T> {
    private int code;
    private String msg;
    private T data;
    // get、set
}

使用:

java 复制代码
Result<User> r1 = new Result<>(); // JDK7钻石语法,右侧自动推导类型

要点:

  1. <T>写在类名后,整个类内部可用T
  2. 静态方法不能使用类定义的泛型T
  3. 不能new T()、不能直接创建T[]数组
  4. 泛型类也可以是JavaBean;普通JavaBean所有字段类型固定,泛型类部分字段类型占位可变。

2.泛型方法

<E>写在方法返回值类型前面,属于方法本身,和类泛型无关。

java 复制代码
public <E> E method(E e){
    return e;
}

类不是泛型类,也可以定义泛型方法;调用时编译器自动推导类型。

二、泛型没有继承性,对象(数据)具备继承性 ✨重点

  1. 对象/数据有继承性(多态成立)
java 复制代码
// meiduan extends animals
animals a = new meiduan("tom",1); // ✅子类对象赋值给父类引用
  1. 泛型不具备继承性 虽然meiduananimals子类,但是ArrayList<meiduan>不是 ArrayList<animals>的子类。
java 复制代码
ArrayList<animals> list = new ArrayList<meiduan>(); // ❌编译报错

泛型参数不同,集合类型之间不存在父子关系。
想要方法接收多种泛型集合,使用通配符

三、通配符 ?

? 无边界通配符 List<?>

可以接收任意类型集合;只能读取,不能add添加元素。

② 上界通配符 ? extends 父类

java 复制代码
List<? extends animals>
  • 可以接收:List<animals>List<bosi>List<meiduan>
  • ✅ 可以读取元素,拿到父类类型
  • 不能add添加元素
  • 使用场景:只读取遍历数据
java 复制代码
public static void keepPet(List<? extends animals> list){
    for(animals c : list){
        c.eat();
    }
}

③ 下界通配符 ? super 子类

java 复制代码
List<? super animals>
  • ✅ 可以存入子类对象
  • ❌ 读取出来只能是Object,拿不到父类
  • 使用场景:主要往集合存数据

记忆口诀 ? extends:读,不能存 ? super:存,读出Object ?:任意集合,不能存

四、类型擦除(面试)

  1. 泛型只存在编译期,运行时泛型信息被擦除。
  2. 无边界<T>擦除为Object<T extends Animal>擦除为Animal
  3. List<String>List<Integer>运行时是同一个List.class
  4. List<Object>List<String>没有父子关系,不能互相赋值;需要用通配符List<?>

五、泛型使用场景

  1. 集合框架:List<E>Map<K,V>,约束元素类型,避免强转异常。
  2. 通用包装类:如Result<T>,一套类适配多种数据,不用重复写多个JavaBean。
  3. 通用工具方法:泛型方法实现一套方法处理多种类型。
  4. 方法形参:通配符,接收多种子类集合。

六、高频错误

  1. 类泛型不能用在静态方法。
java 复制代码
class A<T>{
    public static void test(T t){} //❌
}
  1. 不能new T()、不能直接创建泛型数组new T[]
  2. main方法不能写泛型:public static <T> void main()错误。
  3. ArrayList<父类>不能接收ArrayList<子类>,泛型无继承;改用通配符? extends
  4. List<? extends 父类>不能add元素。

七、泛型类 vs 普通JavaBean

对比项 普通JavaBean 泛型类
属性类型 全部固定写死 部分属性<T>占位,使用时确定真实类型
代码复用 业务类型改变,需要新建Bean 一套类,传入不同类型复用
典型用途 业务实体(User、Order) 容器、返回值包装、工具封装

JavaBean是编码规范,泛型是语法特性;泛型类也可以是JavaBean。

八、背诵简答题

  1. 泛型作用:编译期类型检查,减少强制类型转换,避免运行类型转换异常。
  2. 泛型没有继承性:子类对象可以赋值父类引用;但是ArrayList<子类>不是ArrayList<父类>的子类。
  3. 通配符:? extends可读不可存;? super可存,读取只能Object。
  4. 类型擦除:运行时去掉泛型信息,替换为Object或者上界父类。
  5. 类上定义的泛型,静态方法不能使用。

九、经典考题

java 复制代码
animals an = new meiduan("tom",1);        //✅ 对象多态,数据具备继承性
ArrayList<animals> list = new ArrayList<meiduan>(); //❌泛型无继承
List<? extends animals> list2 = new ArrayList<meiduan>(); //✅通配符
相关推荐
fengyangaiGEO11 分钟前
GEO 如何分析竞品的 AI 引用情况?
人工智能·python·信息可视化
北风toto21 分钟前
扩展操作码技术 · 详细笔记
运维·服务器·笔记·软件设计师
新时代牛马32 分钟前
SPL-TPL 链式启动:spl.c 与CONFIG_TPL 三阶段加载
c语言·开发语言
布莱克60536 分钟前
链表详解:定义、作用、应用场景及与数组的区别(C/C++ 实战)
c语言·开发语言·c++·链表
2601_9669496544 分钟前
实时行情中的成交量 Volume 到底是什么?包含盘中撤单量吗?从交易数据语义到 QuantDash 实战解析
开发语言·人工智能·python·量化·quantdash·量化数据源
you鬰1 小时前
datawhale--llm-algo-leetcode9️⃣ SFT Training Loop
python·datawhale
叫我:松哥1 小时前
基于flask仿小米商城管理系统,使用flask开的一个商场网站
数据库·后端·python·flask
Z5998178411 小时前
c#软件开发学习笔记--WPF(Canvas、数据绑定、MVVM模式、值转换器)
笔记·学习·c#
茯苓gao1 小时前
从零开发 EtherCAT 主站(六):SOEM 初始化流程详解,主站是如何发现所有从站的?
笔记·嵌入式硬件·学习·信息与通信