13、Java 基础硬核复习:泛型(类型安全)的核心逻辑与面试考点
一、核心知识体系:泛型的"三大维度"与"四大专题"
本章的知识围绕"泛型基础、泛型应用、泛型高级特性"展开,可归纳为三大维度 (基础概念、应用场景、高级特性)和四大专题(泛型理解、集合/比较器中的泛型、自定义泛型、通配符)。
1. 泛型的基本概念:类型参数化
泛型是Java 5引入的特性,核心是类型参数化 ,用于在编译时检查类型安全,避免运行时的ClassCastException。
- 作用 :让集合、类、方法可以处理多种类型,同时保持类型安全(如
List<String>只能存储String,编译时检查,运行时无需强制转换)。 - 语法 :使用
<>定义类型参数,如List<T>、class Box<T>。
2. 泛型在集合与比较器中的应用
泛型在集合框架和比较器中广泛应用,是泛型的核心使用场景:
- 集合中的泛型 :
List<String>、Map<String, Integer>等,限制容器只能存特定类型(如List.add(123)会编译报错)。 - 比较器中的泛型 :
Comparable<T>(自然排序)和Comparator<T>(定制排序),如class Student implements Comparable<Student>,或Comparator<Student>,确保比较的类型一致(避免compareTo方法中类型判断)。
3. 自定义泛型类与泛型方法
自定义泛型可以提升代码复用性,需掌握其语法和规则:
- 泛型类 :
class Order<T> { private T item; public void set(T item) { this.item = item; } },Order<String>只能存储String。 - 泛型方法 :
public <E> E get(E e)(方法独立于类,可处理任意类型),注意:泛型方法必须声明<E>,而使用类泛型参数的方法(如public T get())是普通方法。 - 案例 :
DAO<T>(数据访问对象),定义泛型接口实现通用CRUD,如UserDAO继承DAO<User>,减少重复代码。
4. 泛型的高级特性:通配符与继承
泛型的高级特性包括通配符和继承规则,是面试的重点:
- 通配符(?) :
? extends T(上界通配符):只读(生产者),如List<? extends Number>可存储Integer/Double,但不能添加元素(未知具体子类)。? super T(下界通配符):只写(消费者),如List<? super Integer>可添加Integer及其子类,但不能获取具体类型。?(无界通配符):List<?>是所有List的公共父类,只能读取Object,不能添加元素。
- 泛型继承规则 :
List<String>不是List<Object>的子类(类型安全限制,避免破坏类型检查)。
二、高频面试考点:必考"死穴",掌握这些=掌握泛型核心
本章的面试题主要考察对**"类型擦除"和 "通配符"的理解,以下是必考考点**:
1. Java 泛型的原理:类型擦除(Type Erasure)(必考 Top1)
- 考点 :
List<String>和List<Integer>在运行时是同一个类吗? - 答案 :是。
- 原理 :Java的泛型是伪泛型 ,编译后泛型信息被擦除(如
List<String>和List<Integer>都变成List),仅编译时做类型检查,运行时无泛型信息(无法通过instanceof判断泛型类型)。
2. List<String>能赋值给List<Object>吗?
- 考点:泛型的继承性。
- 答案 :不能。
- 原因 :若允许赋值,通过
List<Object>引用可存Integer,但实际对象是List<String>,取数据时会报ClassCastException,破坏类型安全。
3. 泛型方法 vs 泛型类中的方法
- 考点:怎么区分泛型方法?
- 答案 :只有方法返回值前声明
<T>的才是泛型方法 (如public <T> T func(T t)),而使用类泛型参数的方法(如public T get())是普通方法。
4. <? extends T>和<? super T>的区别(PECS原则)
- 考点:什么时候用extends,什么时候用super?
- 口诀 :PECS(Producer Extends, Consumer Super) 。
- 生产者(读取数据):用
extends(如List<? extends Number>获取Number或子类)。 - 消费者(写入数据):用
super(如List<? super Integer>添加Integer或子类)。
- 生产者(读取数据):用
5. 泛型类中可以定义静态泛型方法吗?
- 答案 :可以 ,但静态泛型方法必须自己声明泛型参数 (如
static <E> void test(E e)),不能使用类的泛型参数(静态方法早于对象存在,类泛型在创建对象时确定)。
三、学习建议:从"理论"到"实践"的跃迁
- 实战练习 :亲手写
BaseDAO<T>(泛型DAO),实现通用增删改查,理解泛型复用性。 - 看源码 :阅读
java.util.Collections.copy源码,学习<? super T>和<? extends T>的应用(PECS原则的最佳案例)。 - 理解类型擦除 :通过反编译
.class文件(如javap -v List.class),观察泛型信息被擦除后的字节码,加深对原理的理解。
四、总结:泛型是"Java类型安全"的核心
第13章是"泛型"的硬核复习,它将你从"掌握集合"带入"类型安全与代码复用"的层面。掌握这些知识,你就能写出更安全、更高效的代码,也能在面试中轻松应对"Java基础"的"进阶考点"。
记住,泛型是Java开发的"类型安全工具"------熟练使用泛型,是成为优秀Java开发者的"进阶技能"。