泛型的核心思想是将类型参数化。
泛型主要目的是提供类型安全和消除类型转换,从而使代码更加健壮和可读。它允许在定义类 、接口、方法 和属性时使用类型参数。
注意:
1、泛型这种语法机制,只在程序编译阶段起作用,只是给编译器参考的(意味着运行阶段泛型没有用)。
2、泛型优点:
2.1、集合中存储的元素类型统一了;
2.2、从集合中取出的元素 类型是泛型指定的类型,不需要进行大量 的"向下转型";
3、泛型的缺点:导致集合中存储的元素缺乏多样性;
4、泛型的作用:
4.1、数据安全
4.2、防止类型转换时出错
泛型基础
ini
List<Integer> integerList = Arrays.asList(1, 2, 3);
简单理解,integerList集合,只能放Integer类型的元素。这个Integer就是泛型
泛型通配符
通配符提供了更灵活的类型匹配。有三种主要的通配符用法:
1、无界通配符<?>
2、上界通配符<? extends T>
3、下界通配符<? super T>
无界通配符
-
定义 :
<?>
可以被看作是<? extends Object>
,它表示任何类型的对象。无界通配符不限制类型参数,可以接受任何类型。 -
使用场景:无界通配符主要用于那些对类型不关心的情况。例如,当方法的实现不依赖于具体的类型时,可以使用无界通配符。它常用于只需读取元素而不关心元素类型的情况下。
示例
下面是一个使用无界通配符的示例:
typescript
java
import java.util.Arrays;
import java.util.List;
public class WildcardExample {
// 定义一个方法,接受一个无界通配符的 List
public static void printList(List<?> list) {
for (Object element : list) {
System.out.println(element);
}
}
public static void main(String[] args) {
List<Integer> integerList = Arrays.asList(1, 2, 3);
List<String> stringList = Arrays.asList("A", "B", "C");
printList(integerList); // 输出: 1 2 3
printList(stringList); // 输出: A B C
}
}
代码说明
-
printList
方法接受一个List<?>
参数,意味着该方法可以接受任何类型的列表(如List<Integer>
、List<String>
等)。 -
在方法的实现中,元素被作为
Object
处理,因为具体的类型并不重要。 -
在
main
方法中,我们创建了一个List<Integer>
和一个List<String>
, 然后将它们传递给printList
方法。
限制
-
读取元素 :虽然可以读取无界通配符列表中的元素,但只能将其作为
Object
处理。 -
添加元素 :在无界通配符的情况下,无法向列表中添加任何元素 (除了
null
),因为编译器不知道列表接受何种类型的元素。
总结
-
无界通配符 (
<?>
) 是一种表示任意类型的通配符,用于那些不关心具体类型的场景。 -
读取操作 是合法的,但返回的元素类型只能是
Object
。 -
写入操作 除了
null
以外是被禁止的。
这种灵活性使得无界通配符在编写与类型无关的代码时非常有用,可以增强代码的复用性和可读性。
上界通配符
-
定义 :
<? extends T>
表示可以接受 T 或 T 的子类型。它用于限制泛型类型为 T 及其子类。 -
使用场景 :当你希望只读取数据 ,而不修改数据时(即只对数据进行读取操作),可以使用上界通配符。
-
示例:
typescriptjava public void printList(List<? extends Number> list) { for (Number number : list) { System.out.println(number); } } List<Integer> integerList = Arrays.asList(1, 2, 3); printList(integerList); // 合法,Integer 是 Number 的子类
-
限制 :在使用
<? extends T>
的情况下,你无法向列表中添加元素,因为编译器只知道列表的元素是 T 或 T 的子类型,无法确定具体类型。例如,你不能添加任何元素到List<? extends T>
中,除了null
。
下界通配符
-
定义 :
<? super T>
表示可以接受 T 或 T 的父类型。它用于限制泛型类型为 T 及其父类。 -
使用场景 :当你希望往集合中添加数据时(即进行写入操作),可以使用下界通配符。
-
示例:
scssjavapublic void addNumbers(List<? super Integer> list) { list.add(1); // 合法,Integer 可以添加到 List<? super Integer> list.add(2); } List<Number> numberList = new ArrayList<>(); addNumbers(numberList); // 合法,Number 是 Integer 的父类
-
限制 :在使用
<? super T>
的情况下,你可以往列表中添加 T 或其子类型的元素,但读取元素时返回的类型只能是 Object,因为编译器知道这个列表的元素是 T 或 T 的父类,而无法确定具体类型。
小结
-
上界通配符 (
<? extends T>
):- 用于读取操作。
- 可以接受 T 的子类。
- 无法添加元素(除了
null
)。
-
下界通配符 (
<? super T>
):- 用于写入操作。
- 可以接受 T 的父类。
- 可以向列表中添加 T 或其子类的元素。
通过正确使用上界和下界通配符,可以编写更加灵活和更具可重用性的泛型代码。