七、泛型
通配符(Wildcards)
通配符 — 上界(`extends`)通配符 — 下界(`super`)通配符 — 无限制通配符 – 继承通配符 — 注意点
通配符(Wildcards)在泛型中,问号 ? 被称为是通配符通常用作变量类型、返回值类型的类型参数不能用作泛型方法调用、泛型类型实例化、泛型类型定义的类型参数 通配符 — 上界(extends)
可以通过 extends 设置类型参数的上界
基本使用:
// 类型参数必须是Number类型或者是Number的子类型
void testUpper(Box extends Number> box) {}
// Integer是Number的子类 Boxp1 = null; testUpper(p1); // 可以 // Number类型可以作为参数 Box p2 = null; testUpper(p2); // 可以 // ? extends Number 表示参数是Number的子类 Box extends Number> p3 = null; // 可以 testUpper(p3); // ? extends Integer 表示参数是Integer的子类, Integer是Number的子类 Box extends Integer> p4 = null; // 可以 testUpper(p4); // String不是Number的子类, 传入testUpeer会报错 Box p5 = null; // testUpper(p5); // 报错
示例:对泛型数组的元素求和方法(传入的必须是Number的子类型)
public class Main {
public static void main(String[] args) {
List is = Arrays.asList(1, 2, 3);
System.out.println(sum(is)); // 6.0
List ds = Arrays.asList(1.2, 2.3, 3.5);
System.out.println(sum(ds)); // 7.0
}
static double sum(List extends Number> list) {
double s= 0.0;
for (Number n : list) {
s += n.doublevalue();
}
return s;
}
}
通配符 — 下界(super)
可以通过 super 设置类型参数的下界
基本使用:
// 类型参数必须是Integer类型或者是Integer的父类型
void testLower(Box super Integer> box) {
Boxp1 = null; testLower(p1); Box p2 = null; testLower(p2); Box super Integer> p3 = null; testLower(p3); Box super Number> p4 = null; testLower(p4);
示例:往泛型数组中添加元素(传入的必须是Integer的父类型)
public class Main {
public static void main(String[] args) {
List is = new ArrayList<>();
addNumbers(is);
System.out.println(is); // [1, 2, 3, 4, 5]
List ns = new ArrayList<>();
addNumbers(ns);
System.out.println(ns); // [1, 2, 3, 4, 5]
}
static void addNumbers(List super Integer> list) {
for (int i = 1; i <= 5; i++) {
list.add(i);
}
}
}
通配符 — 无限制
// 类型参数是什么类型都可以
void test(Box> box) {}
Boxp1 = null; Box p2 = null; Box p3 = null; Box extends Number> p4 = null; Box super String> p5 = null; Box> p6 = null; test(p1); test(p2); test(p3); test(p4); test(p5); test(p6);
示例:打印泛型数组的元素(无限制,任何类型都可以)
public class Main {
public static void main(String[] args) {
List is = Arrays.asList(1, 2, 3);
printList(is); // 1 2 3
List ds = Arrays.asList(1.2, 2.3, 3.5);
printList(ds); // 1.2 2.3 3.5
}
static void printList(List> list) {
for (Object object : list) {
System.out.print(object + " ");
}
System.out.println();
}
}
通配符 – 继承
无限制的绝对是最顶层的,其余的按正常继承关系理解即可
通配符 — 注意点编译器在解析 List.set(int index, E element) 时,无法确定E 的真实类型,所以报错



