Skip to content

什么是泛型?有什么作用?

什么是泛型

  • 定义
  • 泛型(Generics)是 Java 中的一种类型参数化机制,允许在定义类、接口或方法时使用占位符(类型参数),在实例化或调用时指定具体类型。
  • 引入
  • JDK 1.5 添加,增强类型安全性。

作用

  1. 类型安全
  2. 编译期检查类型错误,避免运行时异常。
  3. 代码复用
  4. 同一代码适配多种类型。
  5. 消除强制转换
  6. 操作泛型对象无需手动转型。

1. 泛型详解

(1) 基本概念

  • 语法
  • <T> 表示类型参数,T 是占位符。
  • 示例
// 泛型类
class Box<T> {
    private T item;
    public void setItem(T item) { this.item = item; }
    public T getItem() { return item; }
}

// 使用
Box<String> box = new Box<>();
box.setItem("hello");
String value = box.getItem(); // 无需转型

(2) 类型参数

  • 命名
  • 常用 T(Type)、E(Element)、K(Key)、V(Value)。
  • 多参数
class Pair<K, V> {
    K key;
    V value;
}
Pair<String, Integer> pair = new Pair<>();

(3) 泛型擦除

  • 原理
  • 编译时泛型被擦除为 Object 或边界类型,运行时无泛型信息。
  • 字节码
Box<String> box; // 编译后:Box box;
  • 限制
  • 不能用泛型创建实例(如 new T())。

2. 作用详解

(1) 类型安全

  • 问题
  • 无泛型时,集合存取需强制转换,易出错。
List list = new ArrayList();
list.add("hello");
list.add(123); // 类型混杂
String s = (String) list.get(1); // ClassCastException
  • 解决
  • 泛型限制类型,编译期报错。
List<String> list = new ArrayList<>();
list.add("hello");
// list.add(123); // 编译错误
String s = list.get(0); // 无需转型

(2) 代码复用

  • 问题
  • 无泛型需为每种类型写类。
  • 解决
  • 泛型类适配多种类型。
Box<Integer> intBox = new Box<>();
Box<String> strBox = new Box<>();

(3) 消除强制转换

  • 问题
  • 无泛型时,取值需转型。
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
  • 解决
  • 泛型自动推导类型。
List<String> list = new ArrayList<>();
String s = list.get(0); // 无需 (String)

3. 泛型的使用方式

(1) 泛型类

class Container<T> {
    T data;
}
Container<Double> c = new Container<>();

(2) 泛型接口

interface Generator<T> {
    T generate();
}
class NumberGenerator implements Generator<Integer> {
    public Integer generate() { return 42; }
}

(3) 泛型方法

public <T> T getFirst(T[] array) {
    return array[0];
}
String s = getFirst(new String[]{"a", "b"});

(4) 通配符

  • ? extends T:上界,读数据。
  • ? super T:下界,写数据。
List<? extends Number> readOnly = new ArrayList<Integer>();
List<? super Integer> writeOnly = new ArrayList<Number>();

4. 延伸与面试角度

  • 优点
  • 安全性:编译检查。
  • 可读性:类型明确。
  • 局限
  • 擦除:运行时无类型信息。
  • 不能用于基本类型(需用包装类)。
  • 实际应用
  • 集合:List<String>
  • 工具类:Pair<K, V>
  • 面试点
  • 问“作用”时,提类型安全。
  • 问“原理”时,提擦除。

总结

泛型通过类型参数化提供类型安全、复用性和简洁性,编译期确保正确性,运行时擦除。作用在于避免错误和转型。面试时,可举集合示例或提通配符,展示理解深度。