📅  最后修改于: 2023-12-03 14:57:36.520000             🧑  作者: Mango
Java 泛型是 Java 5 中引入的一个新特性,它为 Java 语言引入了参数化类型的概念,以便作为一个通用的类型来处理数据。
早期的 Java 版本只支持指定参数类型的方法,例如 String
类型的 List
。这种方法非常局限性,如果要处理其他类型,那么需要为每个类型写一个新的方法。
使用 Java 泛型的好处在于可以创建适用于多种类型的代码。不仅减少了代码的冗余,还能保证类型安全和提高代码可读性。
除此之外,泛型还能在编译时检查类型错误,并提供更好的异常处理,让开发更加优雅和高效。
Java 泛型可以定义类、接口和方法,下面是这三种方法的定义方式:
在类名后加上 <T>
,T 就是泛型类型,意思是这个类可以接受任何类型参数。
public class Box<T> {
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
泛型接口和泛型类一样,只需将接口名后的 <T>
换成自己需要的泛型标识符即可。
public interface Pair<T, V> {
public T getKey();
public V getValue();
}
泛型方法可以在方法上加上泛型声明,并使用泛型类型参数。
public class Util {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
}
这是一个打印数组元素的泛型方法,在使用时需要传入一个泛型数组。
Java 泛型中还引入了通配符,用以表示未知类型的参数。
无限制通配符使用 <?>
来表示。
public void process(List<?> list) {
for (Object obj : list) {
// do something
}
}
这里的 <?>
表示这个方法可以处理任何类型的 List
,但是对于集合内容的操作只能进行基本操作,例如读取元素值。
有限制通配符表示参数类型必须满足某些条件,用 <? extends T>
或 <? super T>
表示。其中,<? extends T>
表示参数类型必须是 T 类型的子类,<? super T>
表示参数类型必须是 T 类型的父类。
例如:
public void process(List<? extends Number> list) {
for (Number n : list) {
// do something
}
}
这里的 <? extends Number>
表示这个方法可以处理 Number
类型的子类,但是不能处理其父类。
Java 泛型与反射配合使用时会有一些问题。Java 泛型在编译时需要进行类型擦除,因此在运行时是无法获取泛型类型参数的。但是,Java 反射可以获取到泛型类型信息。
例如:
public class Box<T> {
private T t;
public Box() {
Class<?> clazz = getClass();
Type tType = clazz.getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) tType;
Type[] types = pt.getActualTypeArguments();
this.t = (T) ((Class) types[0]).newInstance();
}
public T get() {
return t;
}
}
这里的 getGenericSuperclass
是获取父类信息的方法,通过这个方法可以获取到泛型类型信息,再通过 newInstance
方法创建泛型对象。但这种方法需要强转类型,经过测试会抛出 ClassCastException 异常。
Java 集合框架中的很多类都是泛型类,例如 List
、Set
、Map
等。使用泛型类可以更加灵活地处理集合中的元素,避免类型转换等问题。
// ArrayList 定义
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
// HashMap 定义
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {}
Java 泛型是 Java 5 中引入的新特性,可以提高代码的复用率、类型安全和可读性,同时它也能和 Java 反射和集合框架配合使用,让开发变得更加高效和优雅。