泛型(generics)是 java 类型系统的重要支柱。
它让代码更安全、更简洁、更通用,是理解现代 java 编程的必修课。
本文将系统讲解 java 泛型的定义、使用、通配符、边界与常见陷阱。
一、为什么需要泛型
在 java 1.5 之前,集合只能存放 object 类型:
list list = new arraylist();
list.add("hello");
list.add(123); // 不安全
string s = (string) list.get(0); // 强制类型转换
缺点:类型不安全、容易出错。
java 1.5 引入 泛型机制(generics),允许在定义类或方法时引入“类型参数”。
list<string> list = new arraylist<>();
list.add("hello");
// list.add(123); // 编译错误
string s = list.get(0); // 无需强转
二、泛型的基本语法
class box<t> { // 定义泛型类
private t value;
public void set(t value) { this.value = value; }
public t get() { return value; }
}
box<integer> box = new box<>();
box.set(100);
integer data = box.get();| 关键点 | 说明 |
|---|---|
<t> | 声明类型参数(type parameter) |
t | 类型变量,可代表任意引用类型 |
box<integer> | 实例化泛型类 |
三、泛型类与泛型接口
泛型类
class pair<k, v> {
private k key;
private v value;
public pair(k key, v value) { this.key = key; this.value = value; }
public k getkey() { return key; }
public v getvalue() { return value; }
}
泛型接口
interface converter<f, t> {
t convert(f from);
}
class stringtointeger implements converter<string, integer> {
public integer convert(string from) {
return integer.valueof(from);
}
}四、泛型方法
方法也可以定义自己的类型参数:
public static <t> void printarray(t[] array) {
for (t element : array) {
system.out.println(element);
}
}
string[] arr = {"a", "b", "c"};
printarray(arr); // 自动推断 t = string⚡ 泛型方法的类型参数与类的泛型参数独立存在。
五、通配符:?的三种形态
通配符 ? 表示未知类型,常用于方法参数中。
| 通配符 | 含义 | 示例 |
|---|---|---|
? | 任意类型 | list<?> list |
? extends t | t 或其子类(上界通配符) | list<? extends number> |
? super t | t 或其父类(下界通配符) | list<? super integer> |
示例:
public static void show(list<? extends number> list) {
for (number n : list) {
system.out.println(n);
}
}
| 写入能力 | 读取能力 |
|---|---|
? extends t | ✅ 读安全 ❌ 写 |
? super t | ✅ 写安全 ❌ 读(只能读为 object) |
六、边界与多重限制
class calculator<t extends number & comparable<t>> {
public boolean isgreater(t a, t b) {
return a.compareto(b) > 0;
}
}
✅ 可指定多个上界,必须先是类后是接口。
七、泛型数组与类型推断
- ❌ 泛型数组不能直接创建:new t[10](类型擦除原因)
- ✅ 可使用 list 或 array.newinstance() 代替。
类型推断:
list<string> list = list.of("a", "b");
var map = map.of(1, "a", 2, "b"); // java 10+
八、泛型的好处与限制
| 优点 | 缺点 |
|---|---|
| ✅ 编译期类型安全 | ❌ 运行时类型擦除 |
| ✅ 代码复用性高 | ❌ 无法创建泛型数组 |
| ✅ 无需强转 | ❌ 不能用基本类型 |
九、常见泛型陷阱
❌ 泛型类型不能用于静态上下文:
class box<t> {
// static t value; // 错误!
}
❌ 泛型类型无法用于 instanceof:
if (obj instanceof box<string>) // 错误:类型擦除导致编译不通过
🔚 总结
| 分类 | 关键语法 | 示例 |
|---|---|---|
| 泛型类 | <t> | class box<t> |
| 泛型方法 | <t> | static <t> void print(t t) |
| 通配符 | ? extends / ? super | list<? super integer> |
| 边界 | t extends number | 限制类型范围 |
到此这篇关于java 泛型详解之类型参数的力量(最新推荐)的文章就介绍到这了,更多相关java泛型参数内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论