Java泛型 通配符

在Java泛型中,通配符(wildcard)是用来表示不确定类型的一种方式。通配符用 ? 表示,可以用于泛型类、泛型方法和泛型接口中。

通配符有两种形式:上界通配符和无界通配符。

上界通配符:表示泛型参数的类型必须是某个类或其子类,使用 extends 关键字指定。例如,<? extends Number> 表示泛型参数的类型是 Number 或其子类。
无界通配符:表示泛型参数的类型可以是任何类型,使用 ? 表示。例如,<?> 表示泛型参数的类型可以是任何类型。

通配符可以用于方法参数、返回值和变量类型中,可以提高代码的灵活性和可读性。

下面是一个使用上界通配符的示例:

public static double sumOfList(List<? extends Number> list) {
    double sum = 0.0;
    for (Number n : list) {
        sum += n.doubleValue();
    }
    return sum;
}

该方法可以接收一个 List 对象,该 List 中的元素是 Number 类型或其子类。在方法中遍历 list 中的元素,将它们转换为 double 类型并相加,最后返回总和。

下面是一个使用无界通配符的示例:

List list = new ArrayList<>();

该语句创建了一个 ArrayList 对象,该对象的元素类型可以是任何类型。在使用这个对象时,需要进行类型转换,例如:

List list = new ArrayList<>();
List intList = (List) list;

需要注意的是,使用通配符会带来一些限制,例如无法向使用通配符的泛型对象中添加元素。

Java泛型通配符有三种形式:,,,分别表示不确定类型,限定类型的上界,限定类型的下界。通配符通常用于泛型方法的参数类型、泛型类的类型参数、以及集合类中的泛型参数。

使用通配符可以使得泛型类型更加灵活,具有更广泛的适用性。下面分别介绍这三种通配符的用法。

通配符
表示任意类型,类似于没有使用泛型时的非泛型类型。例如,可以使用List表示可以存储任意类型的列表。使用的好处是可以使得代码更加通用和灵活。

List<?> list = new ArrayList<>();
list.add(null);  // 可以添加 null 值,因为 null 可以表示任意类型
// list.add("foo");  // 不能添加任意类型的元素,因为类型不确定
<? extends T>通配符
<? extends T>表示泛型类型的上界,表示该通配符可以匹配T或T的子类。使用<? extends T>的好处是可以使得方法或类更加通用和灵活。

List<? extends Number> list1 = new ArrayList<>();
List<? extends Integer> list2 = new ArrayList<>();
// list1 = list2;  // 编译错误,因为 list2 的类型是 List<? extends Integer>,不是 List<? extends Number>
list1 = list2;  // 正确,因为 Integer 是 Number 的子类
<? super T>通配符
<? super T>表示泛型类型的下界,表示该通配符可以匹配T或T的父类。使用<? super T>的好处是可以使得方法或类更加通用和灵活。

List<? super Integer> list1 = new ArrayList<>();
List<? super Number> list2 = new ArrayList<>();
// list1 = list2;  // 编译错误,因为 list2 的类型是 List<? super Number>,不是 List<? super Integer>
list2 = list1;  // 正确,因为 Integer 是 Number 的子类

总之,Java泛型通配符是一种非常有用的特性,可以使得泛型类型更加通用和灵活,但是使用时需要注意通配符的上下界限制。