Java 泛型(Generics),简单来说就是:

把“类型”当作参数传递,让同一套代码可以安全地处理不同类型的数据。

比如你经常写:

List<String> names = new ArrayList<>();
List<Integer> ages = new ArrayList<>();

这里的:

<String>
<Integer>

就是泛型。

为什么需要泛型?

没有泛型时:

List list = new ArrayList();
 
list.add("张三");
list.add(18);
list.add(new User());

什么都能放进去。

取出来时:

String name = (String) list.get(0);

需要强制类型转换,而且如果写错:

String name = (String) list.get(1);

运行时就可能:

ClassCastException

使用泛型:

List<String> list = new ArrayList<>();
 
list.add("张三");
list.add("李四");
 
list.add(18); // 编译直接报错

因此泛型最大的作用是:

把很多类型错误提前到编译阶段发现,同时减少强制类型转换。

泛型不只是集合

还可以定义泛型类:

class Box<T> {
 
    private T data;
 
    public void setData(T data) {
        this.data = data;
    }
 
    public T getData() {
        return data;
    }
}

使用:

Box<String> box1 = new Box<>();
box1.setData("hello");
 
Box<Integer> box2 = new Box<>();
box2.setData(100);

这里的 T 可以理解成:

暂时不知道具体是什么类型,使用的时候再告诉我。

例如:

Box<T>
 
Box<String>
    ↓
T = String
 
Box<Integer>
    ↓
T = Integer

还可以有泛型方法:

public <T> T getData(T data) {
    return data;
}

以及泛型接口:

interface MyInterface<T> {
    T get();
}

面试怎么回答?

面试官问:

什么是 Java 泛型?

你可以回答:

泛型是 Java 提供的一种参数化类型机制,可以把类型作为参数传递。例如 List<String> 中的 String 就是泛型参数。泛型可以让同一套代码适用于不同的数据类型,同时在编译阶段进行类型检查,减少运行时的类型转换错误,也可以减少显式的强制类型转换。Java 中主要有泛型类、泛型接口和泛型方法。

再记一句:

泛型 = 参数化类型,把具体类型推迟到使用时再确定。