泛型
泛型
67. 什么是泛型?有什么作用?
回答:
Java 泛型是一种支持"参数化类型"的语法机制,允许在类、接口和方法中使用占位符表示类型,从而在不牺牲类型安全的前提下提升代码的复用性和可读性。
分析:
泛型(Generics)是 JDK 5 引入的重要特性。它允许我们在定义类、接口或方法时使用类型参数,避免在使用集合或容器类时频繁进行类型强制转换,同时在编译阶段实现类型检查,从源头上提升类型安全。
以集合为例:
List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0); // 不需要强转若不使用泛型,则 list.get(0) 返回 Object 类型,必须手动强转为 String,既繁琐又容易出错。
泛型的本质是"伪泛型",即泛型信息只存在于编译期,编译后通过类型擦除(Type Erasure)移除具体类型,用 Object 代替,但在编译期间已确保类型安全。
泛型作用总结:
- 编译期类型检查,提升安全性
- 省去强制类型转换,增强可读性
- 提升代码复用,适配多种类型
泛型是 Java 集合框架、工具类、数据库框架(如 MyBatis)等核心机制的基石。
68. 泛型的使用方式有哪几种?
回答:
Java 泛型主要有三种使用方式:泛型类、泛型接口、泛型方法。除此之外,还有通配符、边界限定等进阶用法。
分析:
- 泛型类
定义在类上的泛型允许在类的字段、方法中引用类型参数。使用时需指定具体类型:
public class Box<T> {
private T value;
public Box(T value) { this.value = value; }
public T getValue() { return value; }
}
Box<String> box = new Box<>("Hello");- 泛型接口
类似于泛型类,可以在接口声明中定义类型参数,并在实现类中明确或继续保留:
public interface Generator<T> {
T next();
}
class StringGenerator implements Generator<String> {
public String next() { return "abc"; }
}- 泛型方法
在方法上声明独立的类型参数,用于灵活处理不同类型输入,典型如工具类的通用方法:
public static <T> void print(T[] array) {
for (T t : array) System.out.println(t);
}注意:静态方法不能访问类上的泛型参数,必须声明自己的类型参数 <T>。
掌握这三种基本用法,是理解 Java 泛型的前提。后续还包括通配符(如 ? extends T)、边界(<T extends Number>)等增强语法,适用于更复杂的泛型表达场景。
69. 项目中哪里用到了泛型?
回答:
在实际项目中,泛型广泛应用于统一返回结构、集合处理、工具类设计、ORM 框架封装等场景,提升代码通用性与类型安全。
分析:
泛型并不是抽象的语法糖,而是很多工程设计中不可或缺的基础能力。例如:
- 统一返回结构设计:如
CommonResult<T>,用于 REST 接口统一封装返回数据类型,通过泛型动态传入响应的数据结构(如列表、分页对象、单条数据等)。
public class CommonResult<T> {
private Integer code;
private String message;
private T data;
}通用工具类:如 Excel 导出工具
ExcelUtil<T>,通过泛型实现对任意对象类型的导出支持,不需要重复为每种类型编写导出逻辑。集合类操作:JDK 自带的工具类如
Collections.sort(List<T>)、Collections.binarySearch(List<T>, T)等均使用泛型,增强了适配性和类型安全。数据库 ORM 封装:如
BaseMapper<T>、JpaRepository<T, ID>,通过泛型实现对实体类的统一操作能力,极大提升代码复用性。
泛型的广泛使用,体现了 Java 强类型语言中追求"既通用又安全"的理念。掌握泛型,是构建高质量中间件与基础库的必修课。