Java 泛型基础

泛型如何在编译期约束集合与 API:类型参数、边界、菱形推断,以及擦除带来的限制入口。

#type / concept #status / growing #tech / dev #resource / java

[!info] 关联笔记

Java 泛型基础

这个概念为什么出现

没有泛型时,集合只能装 Object,取出靠强转,错误拖到运行时。泛型把“这是订单列表还是用户列表”变成编译期检查,同时通过类型擦除保持与旧 JVM 的兼容。

[!abstract] 一句话理解 泛型用类型参数在编译期约束 API 与集合元素类型;运行时大部分类型参数被擦除,因此不能 new T()/new T[] 等可具体化操作。

最小可运行示例

场景:仓库服务的通用“货架盒”只允许同类型货物

import java.util.ArrayList;
import java.util.List;

final class Box<T> {
    private final List<T> items = new ArrayList<>();
    void put(T item) {
        if (item == null) throw new IllegalArgumentException("item");
        items.add(item);
    }
    T get(int index) { return items.get(index); }
    int size() { return items.size(); }
}

public class BoxDemo {
    // 泛型方法:取首个非空
    static <T> T firstNonNull(T a, T b) {
        return a != null ? a : b;
    }
    public static void main(String[] args) {
        Box<String> skuBox = new Box<>();
        skuBox.put("SKU-1");
        // skuBox.put(1); // 编译错误
        System.out.println(skuBox.get(0));
        System.out.println(firstNonNull(null, "X"));
    }
}

建议运行:

javac BoxDemo.java && java BoxDemo

期望输出:

SKU-1
X

结合场景再看三个关注点

  1. 错误在编译期暴露,不用等到生产 ClassCast。
  2. Box<String>Box<Object> 不变(invariant)
  3. 擦除限制在进阶篇展开,但现在起避免 raw type。

核心概念与准确模型

1. 类型参数

  • 类/接口:class Repo<T>
  • 方法:<T> T id(T x)
  • 多参数:Map<K,V>

2. 边界

class NumBox<T extends Number> { }

上界限制可用方法;通配符 ? extends/? super 服务 PECS(进阶常用)。

3. 菱形推断

List<String> list = new ArrayList<>();

4. 擦除直觉

  • 运行时 List<String>List<Integer> 的类字面量同为原始集合类型相关形态
  • 不能依赖运行时 Tinstanceof T

边界情况与反直觉行为

  1. 原始类型 List 关闭泛型检查——遗留炸弹。
  2. 泛型数组创建受限。
  3. 桥接方法由编译器生成(反编译可见)。

常见误区

[!warning] 常见误区:到处 @SuppressWarnings(“unchecked”) 先修类型设计;压制警告只在边界层且有证明时。

工程实践

  1. 公共 API 全程泛型化,禁止 raw。
  2. 生产者 ? extends,消费者 ? super(PECS)。
  3. 复杂通配符用类型别名/中间类型简化。
  4. 与集合框架一起练:List/Map/Optional

本节总结

  • 泛型=编译期安全 + 表达能力
  • 擦除=运行时限制来源
  • 不用 raw type

自测题

  1. 为什么不能写 new T()
  2. List<String> 能否传给 List<Object> 参数?
参考答案
  1. 擦除后缺少可具体化类型信息,且构造约束复杂。
  2. 不能直接传(不变性);否则能放入 Integer 破坏类型安全。

延伸阅读与资料来源

资料类型支撑内容
Generics (Oracle Tutorial)教程泛型体系
JLS Types - Generics规范类型系统
创建于 2026/7/15 更新于 2026/7/15