泛型
泛型不支持基本数据类型(如 int、double),只能使用引用类型(对象)。
泛型擦除
Java 的泛型只存在于编译阶段。
java
List<Integer> list = new ArrayList<>();编译后会变成:
java
List list = new ArrayList();- 泛型类型信息在运行时被“擦除”
- JVM底层使用的是 Object,这是因为早期JDK并没有泛型,添加泛型后需要确保兼容之前的版本
为什么需要泛型
使用泛型之前
java
List list = new ArrayList();
list.add("hello");
list.add(123); // 也能加
String str = (String) list.get(1); // 运行时才报错- 类型不安全(什么都能放)
- 需要强制类型转换
- 错误发生在运行时
使用泛型之后
java
List<String> list = new ArrayList<>();
list.add("hello");
// list.add(123); // 编译直接报错
String str = list.get(0); // 不需要强转- 编译期检查类型
- 不需要强制转换
- 代码更清晰
泛型参数
泛型类
java
public class Box<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}创建对象时指定泛型参数:
java
Box<String> box = new Box<>();
box.set("hello");
String val = box.get();泛型方法
泛型参数 <T> 需要写在返回值前面,表示这个方法是一个泛型方法,泛型参数来着方法调用者,而不是来自class
java
public <T> void test(T a, T b) {}泛型参数根据传入的形参自动推断出类型
java
test(1, 2); // T = Integer
test("a", "b"); // T = String泛型接口
java
public interface Converter<T> {
T convert(String input);
}实现接口时,指定泛型接口的参数:
java
public class IntegerConverter implements Converter<Integer> {
public Integer convert(String input) {
return Integer.valueOf(input);
}
}泛型与静态成员
泛型类
静态成员不能使用类的泛型,是因为在泛型类中,泛型属于“对象”,而静态属于“类”
java
public class Test<T> {
static T value; // ❌ 编译报错
}泛型类中的泛型是属于实例级别的:
java
Test<String> t1 = new Test<>();
Test<Integer> t2 = new Test<>();泛型方法
对于泛型方法,泛型属于方法的,因此可以定义一个静态泛型方法
