泛型知识笔记

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. 泛型不具备继承性 虽然meiduan是animals子类,但是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>(); //✅通配符
相关推荐
weixin199701080168 分钟前
《1688消息服务落地方案:alibaba.message.* 与 Webhook 回调的可靠性与重试策略》(附Python源码)
开发语言·python
北风toto8 分钟前
数据库笔记:Armstrong 公理系统与集合论的深度辨析
数据库·笔记
EasyBr指纹浏览器10 分钟前
我的开源项目:小红书笔记归档,把来源和缺项一起留下
笔记·小红书·开源工具·素材管理·内容归档
海海不掉头发11 分钟前
图论及其应用_课堂笔记整理_CSDN博客
笔记·图论
志尊宝15 分钟前
Vue3 零基础每日笔记(075):图片懒加载与骨架屏
javascript·vue.js·笔记
ZHOUPUYU18 分钟前
PHP 9.0 前瞻:下一代 PHP 会带来哪些新功能?
android·开发语言·php
某不知名網友18 分钟前
ROS2 核心通信:话题发布与订阅详解
开发语言·c++
一只专注api接口开发的技术猿18 分钟前
Open‑Claw 实战|告别页面逆向,快速搭建电商商品监控与数据分析完整方案
大数据·数据库·python·数据挖掘·数据分析
C++ 老炮儿的技术栈19 分钟前
char (*csConnectName)[256]; 和 char csConnectName [256] 有什么区别
java·c语言·开发语言·c++·人工智能·算法·c
Nebula_g30 分钟前
JavaSE加强:线程Thread(线程安全重点)
java·开发语言·jvm·算法·javase·技术栈