文章目录
前言
“听说过泛型,但从来没用过”,你是不是也这么说?
“泛型?我用了呀,就是 <T>
这个东西嘛。”你是不是这么想?
那今天这篇文章,就让你从泛型菜鸟进化成泛型大厨,写出别人看到想点赞,自己看了想加班的代码!
一、泛型到底是啥?(别怕,看完你就懂!)
通俗地说,泛型就是让代码更通用、更安全、更省事的一个神器。
想象一下,你有一个百宝箱,这个箱子可以装不同类型的东西(比如水果、蔬菜、工具),但你不用再为每种类型单独买个箱子。泛型就是给你这个“百宝箱”的!
代码类比:
没有泛型的时候:
List list = new ArrayList();
list.add("苹果");
list.add(123); // 我是谁?我在哪?我为什么能进来?
有了泛型以后:
List<String> fruits = new ArrayList<>();
fruits.add("苹果");
// fruits.add(123); // 报错:123 不是水果!
泛型的两个好处:
- 类型安全:防止“李逵”混入“李鬼”。
- 避免强制类型转换:省去
Object
的转换烦恼。
二、泛型的实战操作(是时候秀肌肉了!)
1. 泛型方法:小而美的实用工具
泛型不仅能用在类上,还能用在方法上!比如你想实现一个工具方法,用来打印任何类型的数组:
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
用法:
String[] fruits = {"苹果", "香蕉", "橘子"};
printArray(fruits); // 输出:苹果、香蕉、橘子
Integer[] numbers = {1, 2, 3};
printArray(numbers); // 输出:1、2、3
这里的 <T>
是个占位符,意思是:这个方法的类型参数可以是任何类型,你调用的时候才指定。
2. 泛型类:开箱即用的百宝箱
如果你要实现一个自己的“盒子”,用来装任何东西,泛型类绝对是你的好帮手:
class Box<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
用法:
Box<String> stringBox = new Box<>();
stringBox.setItem("泛型大法好!");
System.out.println(stringBox.getItem()); // 输出:泛型大法好!
Box<Integer> intBox = new Box<>();
intBox.setItem(42);
System.out.println(intBox.getItem()); // 输出:42
3. 边界约束:泛型的“圈地运动”
有时候你不想让泛型太自由(比如不能让“老虎”跑进“羊圈”),可以用 extends 和 super 限制它的类型范围。
例子:我们只允许装水果或水果的子类(比如苹果、香蕉):
class Fruit {}
class Apple extends Fruit {}
class FruitBox<T extends Fruit> {
private T fruit;
public void setFruit(T fruit) {
this.fruit = fruit;
}
public T getFruit() {
return fruit;
}
}
用法:
FruitBox<Apple> appleBox = new FruitBox<>();
appleBox.setFruit(new Apple()); // 妥妥的!
// FruitBox<String> stringBox = new FruitBox<>(); // 报错:不是水果!
三、泛型的常见“坑点”(别掉坑,划重点!)
-
泛型不能用基本类型
你想用List<int>
?抱歉,Java 不允许!需要用包装类,比如List<Integer>
。 -
类型擦除
Java 的泛型在运行时会被“擦除”,意思是泛型信息只存在于编译阶段,运行时全变成了Object
。
示例:
List<String> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
System.out.println(list1.getClass() == list2.getClass()); // true
- 静态成员不能使用泛型
因为泛型是类级别的,而静态成员是全局共享的,二者冲突。
四、总结(最后的升华)
泛型,是 Java 中为数不多的“既优雅又实用”的工具。掌握泛型,你的代码不仅能跑得更快,还能笑得更帅!
所以,下次写代码时,不妨想想:
“这里用泛型,能不能更优雅一点?”
今天的小挑战:写一个泛型类,支持装多个物品,但只能拿出来符合指定类型的物品,试试看吧!
五、彩蛋:一句话概括泛型
泛型就像个“万能接口”,能让代码 强类型约束 和 灵活扩展性 并存。
记住:T
,不仅是类型,更是“代码世界的未来”!
推荐阅读文章
- 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)
- 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系
- HTTP、HTTPS、Cookie 和 Session 之间的关系
- 什么是 Cookie?简单介绍与使用方法
- 什么是 Session?如何应用?
- 使用 Spring 框架构建 MVC 应用程序:初学者教程
- 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误
- 如何理解应用 Java 多线程与并发编程?
- 把握Java泛型的艺术:协变、逆变与不可变性一网打尽
- Java Spring 中常用的 @PostConstruct 注解使用总结
- 如何理解线程安全这个概念?
- 理解 Java 桥接方法
- Spring 整合嵌入式 Tomcat 容器
- Tomcat 如何加载 SpringMVC 组件
- “在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”
- “避免序列化灾难:掌握实现 Serializable 的真相!(二)”
- 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)
- 解密 Redis:如何通过 IO 多路复用征服高并发挑战!
- 线程 vs 虚拟线程:深入理解及区别
- 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
- 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!
- “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”
- Java 中消除 If-else 技巧总结
- 线程池的核心参数配置(仅供参考)
- 【人工智能】聊聊Transformer,深度学习的一股清流(13)
- Java 枚举的几个常用技巧,你可以试着用用