1. 引言

jdk5.0中引入了Java泛型,目的是减少错误,并在类型上添加额外的抽象层。

本文将简要介绍Java中的泛型、泛型背后的目标以及如何使用泛型来提高代码的质量。

泛型方法

泛型方法是用单个方法声明编写的方法,可以用不同类型的参数调用。编译器将确保所用类型的正确性。以下是泛型方法的一些属性:

  1. 泛型方法在方法声明的返回类型之前有一个类型参数(包裹类型的菱形运算符)
  2. 类型参数可以有界(边界将在本文后面解释)
  3. 泛型方法可以具有不同的类型参数,这些参数在方法签名中用逗号分隔
  4. 泛型方法的方法体与普通方法一样

定义将数组转换为列表的泛型方法的示例:

public <T> List<T> (T[] a) {
    return Arrays.stream(a).collect(Collectors.toList());
}

方法声明中的表示该方法将处理泛型类型 T。即使方法返回的是void,也需要这样做。
如上所述,方法可以处理多个泛型类型,在这种情况下,所有泛型类型都必须添加到方法声明中,例如,如果我们要修改上面的方法来处理类型 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),则必须将其放在边界列表的第一位。否则,将导致编译时错误。

原文地址: https://www.cnblogs.com/liululee/p/13962255.html