9.3.4 设定泛型形参的上限

9.3.4 设定泛型形参的上限

Java泛型不仅允许在使用通配符形参时设定上限,而且可以在定义泛型形参时设定上限,用于表示传给该泛型形参的实际类型要么是该上限类型,要么是该上限类型的子类

设置单个类上限

下面程序示范了这种用法。

1
2
3
4
5
6
7
8
9
10
11
public class Apple<T extends Number> {
T col;

public static void main(String[] args) {
Apple<Integer> ai = new Apple<>();
Apple<Double> ad = new Apple<>();
// 下面代码将引起编译异常,下面代码试图把String类型传给T形参
// 但String不是Number的子类型,所以引发编译错误
// Apple<String> as = new Apple<>(); // 代码1
}
}

上面程序定义了一个Apple泛型类,该Apple类的泛型形参的上限是Number类,这表明使用Apple类时为T形参传入的实际类型参数只能是NumberNumber类的子类。上面程序在代码1 处将引起编译错误:类型T的上限是Number类型,而此处传入的实际类型是String类型,既不是Number类型,也不是Number类型的子类型,所以将会导致编译错误。

可以设置一个类上限 多个接口上限

在一种更极端的情况下,程序需要为泛型形参设定多个上限(至多有一个父类上限,可以有多个接口上限),表明该泛型形参必须是其父类的子类(是父类本身也行),并且实现多个上限接口。如下代码所示。

1
2
3
4
5
import java.io.Serializable;
// 表明T类型必须是 Number类或其子类,并必须实现java.io.Serializable接口
public class Apple2<T extends Number & Serializable> {
// ......
}

类上限要写在接口上限前面

与类同时继承父类、实现接口类似的是,为泛型形参指定多个上限时,所有的接口上限必须位于类上限之后。也就是说,如果需要为泛型形参指定类上限,类上限必须位于第一位。