泛型的本质是参数化类型,通常用于输入参数、存储类型不确定的场景。相比于直接使用 Object 的好处是:编译期强类型检查、无需进行显式类型转换。
上限:泛型中 ? 可以用来做通配符,单纯 ? 匹配任意类型。< ? extends T > 表示类型的上界是 T,参数化类型可能是 T 或 T 的子类;
下限:除了 extends 还有一个通配符 super,< ? super T > 表示类型的下界是 T,参数化类型可以是 T 或 T 的超类;
package com.lnu.test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Test {
static class Food {}
static class Fruit extends Food {}
static class Apple extends Fruit {}
public static void main(String[] args) throws IOException {
ArrayList<Food> foods = new ArrayList<>();
ArrayList<Fruit> fruits = new ArrayList<>();
ArrayList<Apple> apples = new ArrayList<>();
// 上限测试 : fruit及其以下
upshow(fruits);
upshow(apples);
// 下限测试 :friut及其以上
downshow(fruits);
downshow(foods);
}
/**
* 通配符上限
* @param list
*/
public static void upshow(List<? extends Fruit> list) {
// 编译错误,因为类型还不知道
// list.add(new Fruit());
for (int i = 0; i < list.size(); i++) {
Fruit fruit = list.get(i);
System.out.println(fruit);
}
}
}
/**
* 通配符下限
* @param list
*/
public static void downshow(List<? super Fruit> list) {
// 可以使用add
// list.add(new Fruit());
for (int i = 0; i < list.size(); i++) {
Fruit fruit = (Fruit) list.get(i);
System.out.println(fruit);
}
}
}
}
总结:
/**
* 这是一个泛型方法的使用
* <K, V>表示有 K 和 V 这两个符号,相当于有两种通配符可以用
* 其中返回值类型为 K
* 参数列表为 K 和 V 类型
* @param k
* @param v
* @param <K>
* @param <V>
* @return
*/
public <K, V> K testFun(K k, V v) {
}