1. 引言
jdk5.0中引入了Java泛型,目的是减少错误,并在类型上添加额外的抽象层。
本文将简要介绍Java中的泛型、泛型背后的目标以及如何使用泛型来提高代码的质量。
泛型方法
泛型方法是用单个方法声明编写的方法,可以用不同类型的参数调用。编译器将确保所用类型的正确性。以下是泛型方法的一些属性:
- 泛型方法在方法声明的返回类型之前有一个类型参数(包裹类型的菱形运算符)
- 类型参数可以有界(边界将在本文后面解释)
- 泛型方法可以具有不同的类型参数,这些参数在方法签名中用逗号分隔
- 泛型方法的方法体与普通方法一样
定义将数组转换为列表的泛型方法的示例:
public <T> List<T> (T[] a) {
return Arrays.stream(a).collect(Collectors.toList());
}
方法声明中的
如上所述,方法可以处理多个泛型类型,在这种情况下,所有泛型类型都必须添加到方法声明中,例如,如果我们要修改上面的方法来处理类型 T 和类型 G ,应该这样写:
public static <T, G> List<G> fromArrayToList(T[] a, Function<T, G> mapperFunction) {
return Arrays.stream(a)
.map(mapperFunction)
.collect(Collectors.toList());
}
我们正在传递一个函数,该函数将具有T类型元素的数组转换为包含G类型元素的列表。例如,将 Integer 转换为其 String 表示形式:
@Test
public void givenArrayOfIntegers_thanListOfStringReturnedOK() {
Integer[] intArray = {1, 2, 3, 4, 5};
List<String> stringList
= Generics.fromArrayToList(intArray, Object::toString);
assertThat(stringList, hasItems("1", "2", "3", "4", "5"));
}
Oracle建议使用大写字母表示泛型类型,并选择更具描述性的字母来表示形式类型,例如在Java集合中,T 用于类型,K 表示键,V 表示值。
2.1泛型边界
如前所述,类型参数可以是有界的。有界意味着“限制”,我们可以限制方法可以接受的类型。
例如,可以指定一个方法接受一个类型及其所有子类(上限)或一个类型所有它的超类(下限)。
要声明上界类型,我们在类型后面使用关键字extends,后跟要使用的上限。例如:
public <T extends Number> List<T> fromArrayToList(T[] a) {
...
}
这里使用关键字extends表示类型 T 扩展类的上限,或者实现接口的上限。
2.2. 多个边界
类型还可以有多个上界,如下所示:
<T extends Number & Comparable>
如果 T 扩展的类型之一是类(即Number),则必须将其放在边界列表的第一位。否则,将导致编译时错误。
评论区