T
是 Java 泛型中最常用的类型参数,代表"Type"(类型)。它在 Java 集合框架和函数式接口中被广泛使用,提供了编译时类型安全检查的能力。
一、T
的基本概念
1. 泛型类型参数
T
是一个占位符,表示某种类型- 在类/接口定义时不确定具体类型
- 在使用时确定具体类型(编译时)
2. 常见形式
csharp
// 类定义中的泛型
public class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// 接口定义中的泛型
public interface Consumer<T> {
void accept(T t);
}
二、T
的实际使用方式
1. 基本使用示例
ini
// 创建Box实例,指定T为String
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String value = stringBox.getContent(); // 不需要强制类型转换
// 创建Box实例,指定T为Integer
Box<Integer> intBox = new Box<>();
intBox.setContent(100);
int num = intBox.getContent(); // 自动拆箱
2. 方法中的泛型
ini
// 泛型方法
public <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
// 使用
String[] strArray = {"A", "B", "C"};
Integer[] intArray = {1, 2, 3};
printArray(strArray); // 输出: A B C
printArray(intArray); // 输出: 1 2 3
三、T
的高级特性
1. 类型边界
scala
// T必须是Number或其子类
public class NumberBox<T extends Number> {
private T number;
public double getDoubleValue() {
return number.doubleValue();
}
}
// 正确使用
NumberBox<Integer> intBox = new NumberBox<>();
NumberBox<Double> doubleBox = new NumberBox<>();
// 错误使用
// NumberBox<String> stringBox = new NumberBox<>(); // 编译错误
2. 通配符
typescript
// 上界通配符
public void processNumbers(List<? extends Number> numbers) {
for (Number num : numbers) {
System.out.println(num.doubleValue());
}
}
// 下界通配符
public void addIntegers(List<? super Integer> list) {
list.add(1);
list.add(2);
}
四、实际应用场景
1. 集合框架
vbnet
List<String> stringList = new ArrayList<>(); // T=String
Map<Integer, String> map = new HashMap<>(); // K=Integer, V=String
2. 函数式接口
rust
// Predicate<T> - 判断条件
Predicate<String> isLong = s -> s.length() > 10;
// Function<T, R> - 转换函数
Function<String, Integer> stringToLength = String::length;
// Consumer<T> - 消费对象
Consumer<String> printer = System.out::println;
3. 自定义泛型类
vbscript
public class Response<T> {
private boolean success;
private T data;
// 构造方法、getter、setter
}
// 使用
Response<String> stringResponse = new Response<>(true, "Success");
Response<User> userResponse = new Response<>(true, new User("Alice"));
4. 工具类方法
typescript
public class CollectionUtils {
// 泛型方法:集合转换
public static <T, R> List<R> transform(List<T> list, Function<T, R> function) {
return list.stream().map(function).collect(Collectors.toList());
}
}
// 使用
List<String> names = Arrays.asList("Alice", "Bob");
List<Integer> nameLengths = CollectionUtils.transform(names, String::length);
五、最佳实践
-
尽量使用泛型:提高代码类型安全性和可读性
-
避免使用原始类型 :如
List
而不是List<String>
-
合理使用通配符:增强API灵活性
-
注意类型擦除:泛型信息在运行时不可用
-
命名约定:
T
表示类型E
表示集合元素类型K
表示键V
表示值R
表示返回值类型
六、常见问题与解决方案
1. 类型擦除问题
arduino
// 无法直接创建泛型数组
// T[] array = new T[10]; // 编译错误
// 解决方案:使用反射或传入Class对象
public <T> T[] createArray(Class<T> clazz, int size) {
return (T[]) Array.newInstance(clazz, size);
}
2. 泛型与静态方法
csharp
// 静态方法不能使用类的泛型参数
public class Box<T> {
// 错误示例
// public static void print(T item) {}
// 正确做法:声明自己的泛型参数
public static <U> void print(U item) {
System.out.println(item);
}
}
3. 多边界限制
scala
// T必须同时实现Serializable和Comparable
public class SerializableComparable<T extends Serializable & Comparable<T>> {
// ...
}
通过合理使用泛型类型 T
,可以编写出更加安全、灵活和可重用的Java代码。