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>>、泛型构造器、桥接方法。日常接口扫描用不到,遇到再说。

相关推荐
eleven_4u16 小时前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
牧瀬クリスだ16 小时前
Redis Hash实战:高效存储对象与购物车
java·数据库·redis·算法·哈希算法
文丑颜不良啊16 小时前
LeetCode1141~1160题目解析
java·leetcode
木井巳16 小时前
【动态规划: 路径问题】下降路径最小和
java·算法·leetcode·动态规划·推荐算法
秋饼16 小时前
MySQL 分库分表完全指南:ShardingSphere-JDBC 实战、分片键选型、场景边界、20 个生产坑与 30 道面试点
java·mysql·面试·shardingsphere·分库分表·后端架构
郭小李16 小时前
spring 的 @CookieValue 注解 用法
java·后端·spring
天远Date Lab17 小时前
零信任架构实战:基于天远企业股权变更构建自动化招投标供应商股东穿透审查网关
java·人工智能·架构·自动化
weixin_3993806917 小时前
TongWeb7.0.4.9M11如何接入到idea(by lqw)
java·ide·intellij-idea
paopaokaka_luck17 小时前
社区服务平台(加权协同过滤推荐、Jieba中文词频分析、WebSocket实时聊天、求助处理闭环、 活动积分闭环、ECharts多维分析)
java·前端·spring boot·mysql·echarts·mybatis
.Bryce.17 小时前
T2-LLM评测不等于Agent评测
android·java·人工智能·后端·gpt·agent·1024程序员节