在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泛型通配符是一种非常有用的特性,可以使得泛型类型更加通用和灵活,但是使用时需要注意通配符的上下界限制。