Java 泛型快速学习指南(面向接口扫描场景)

Java 泛型快速学习指南(面向接口扫描场景)

目标:让你能读懂 / 看懂被扫描 Java 代码里的泛型,理解扫描工具在「DTO 展开、包装类解包」时到底在干什么。

不需要背语法细节,重点是建立直观理解。
摘要 :本文用最短篇幅讲清 Java 泛型的核心概念------泛型是给容器/方法提前声明的占位类型,编译期定死类型、免强转。内容覆盖泛型类、泛型方法、多类型参数、泛型嵌套(Result<List<OrderDTO>> 这类"套娃")、通配符 ?、数组/List 两行式输出口径,以及泛型擦除为何导致运行时拿不到 T。文末附最小速查表,面向接口扫描场景,帮你建立直观理解、读懂被扫描代码里的泛型。


一、泛型是什么(一句话)

泛型 = 给"容器/方法"提前声明一个"占位类型 T",使用时再填上具体类型。

没有泛型时,集合里放的是 Object,取出来要强转,容易出错:

java 复制代码
List list = new ArrayList();
list.add("abc");
String s = (String) list.get(0); // 必须强转,类型不安全

有了泛型,类型在编译期就定死,取出来直接用:

java 复制代码
List<String> list = new ArrayList<>();
list.add("abc");
String s = list.get(0); // 不需要强转,编译器保证里面一定是 String

核心好处:编译期类型检查 + 免强转。


二、最基本的几种写法

1. 类上的泛型(泛型类)

java 复制代码
class Box<T> {        // T 是类型占位符,名字随便起(常用 T/E/K/V)
    private T value;
    public T getValue() { return value; }
    public void setValue(T value) { this.value = value; }
}
// 使用时:
Box<String> b = new Box<>();
b.setValue("你好");    // 这里 T 被"填"成了 String

2. 方法上的泛型(泛型方法)

java 复制代码
public <T> T getFirst(List<T> list) {
    return list.get(0);
}
// 调用时 T 由实参自动推断
String s = getFirst(Arrays.asList("a", "b"));

3. 多个类型参数

java 复制代码
class Pair<K, V> {
    private K key;
    private V value;
}
// 你项目里常见:Map<String, OrderDTO> 就是 K=String, V=OrderDTO

三、你最可能遇到的"套娃"类型

1. 泛型嵌套(重点)

java 复制代码
List<OrderDTO>            // 元素类型是 OrderDTO
Result<List<OrderDTO>>    // Result 包裹 List,List 包裹 OrderDTO
Page<OrderVO>             // 分页对象,里面是 OrderVO 列表

理解口诀:从外往里一层层剥。扫描工具也正是这么做的:

  • 看到 Result<T> → 先把 Result 这个"容器"当一行;
  • 再把 T(实参)树挂到它下面继续展开。

2. 通配符 ?(你大概只需知道它存在)

java 复制代码
List<?>          // 任意类型的 List
List<? extends Number>  // 元素类型是 Number 或其子类(上界)
List<? super Integer>   // 元素类型是 Integer 或其父类(下界)

实际扫描里一般不用深究,工具多半按"保留容器行 + 不强行展开"处理。

3. 数组 / List 两行式(对应你工具的输出口径)

源码:

java 复制代码
private List<OrderItemDTO> items;

输出报文里会变成两行:

  • 数组行:items type=List<OrderItemDTO>
  • 元素行:挂在 items 下,name=OrderItemDTO,继续展开其字段

四、泛型擦除(为什么运行时拿不到 T)

Java 的泛型是编译期 的:编译完之后,List<String> 和 List<Integer> 在 JVM 里都是同一个 List(类型信息被"擦掉")。

java 复制代码
// 编译后等价于:
List list = new ArrayList();

这解释了:

  • 为什么不能 new T()、不能 new List<T>()(运行时不知道 T 是谁);
  • 为什么扫描工具必须靠读源码/字节码里的声明来还原泛型,而不能在运行时探测。

五、最小速查表

写法 读法
T / E / K / V 类型占位符(Type/Element/Key/Value)
List<String> 装 String 的列表
Map<String, OrderDTO> key=String, value=OrderDTO 的映射
Result<T> 泛型包装容器,T 是真正的业务数据
Result<List<X>> 包装容器里套了一个 X 列表
? extends X X 或其子类
? super X X 或其父类

想深入再补:泛型边界 <T extends Comparable<T>>、泛型构造器、桥接方法。日常接口扫描用不到,遇到再说。

相关推荐
Escalating_xu6 小时前
【C 语言】数据在内存中的存储:补码、大小端、整型陷阱与 IEEE 754 全解析
java·c语言·网络
灯澜忆梦6 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
一个风轻云淡6 小时前
GCC 和 GDB命令简单解读
java·linux·前端
省钱兄--zs6 小时前
西安24小时自助健身房解决方案实战:系统开发与部署全流程指南
java·spring boot·系统架构·intellij-idea·需求分析
资料库016 小时前
Linux 8个常见运维故障排查
java·linux·运维
要开心吖ZSH7 小时前
MySQL 慢 SQL 排查操作手册-个人笔记版
java·笔记·sql·mysql·慢查询
Joy T8 小时前
Spring AI 接入已有 Java 项目的三种架构设计
java·人工智能·springai·ai入门·chatclient·ai service·ai能力接入
杨运交8 小时前
[076][核心模块]构建优雅的Java异常处理框架:从错误码到全局异常处理
java·开发语言
caoerzhong8 小时前
仓库数字化成熟度分级:JeeWMS 开源 Java 仓库管理系统如何支撑从可见到自治的四级跃迁
java·开源
MayBaymax8 小时前
RocketMQ 存储机制
java·rocketmq