在Java中,泛型通配符允许我们在定义方法参数或变量时,接受不同类型的泛型实例。了解通配符的上限和下限,以及野蛮类型,有助于编写更具通用性的代码。以下是一些关键概念、常见问题及其解决方案,以及代码示例。

? extends T表示类型是T或其子类型。T被称为上限类型。 void addToList(List<? extends Number> numbers) {
numbers.add(10); // 错误,不能添加元素
Number num = numbers.get(0); // 正确,可以安全地读取
}? super T表示类型是T或其父类型。T被称为下限类型。 void copyNumbers(List<? super Number> dest, List<Number> src) {
dest.addAll(src); // 正确,可以添加元素
Number num = dest.get(0); // 错误,编译错误,无法安全地读取
}List而不是List<String>。 List list = new ArrayList(); // 野蛮类型
list.add("String"); // 可以添加任何类型
Object obj = list.get(0); // 获取的是Object类型,需要显式转换List<? extends Number> numbers = new ArrayList<>()是不允许的。List<Number> numbers = new ArrayList<Number>()。? extends Number & Comparable<?>是非法的。理解并熟练使用泛型通配符的上限、下限和野蛮类型,可以编写出更灵活且类型安全的代码。然而,过度使用通配符可能导致代码可读性降低,因此在设计API时要权衡通用性和清晰度。