Java泛型深入解析:T与问号(通配符)的区别

版权申诉
1 下载量 139 浏览量 更新于2024-09-13 1 收藏 75KB PDF 举报
"Java泛型中T与问号(通配符)的区别" 在Java编程语言中,泛型是一种强大的工具,它允许我们在编译时检查类型安全并提高代码的重用性。Java泛型引入了两种主要的概念:类型参数(如T)和通配符(如?)。本文将详细讨论这两者的差异。 1. 类型参数(T) 类型参数,通常以大写字母T(代表"Type")表示,是我们自定义的一个占位符,用于代表任意的类型。在定义泛型类或泛型方法时,我们可以使用T作为类型参数,然后在类的实例化或方法调用时指定具体的类型。例如,以下是一个简单的泛型类`Gen<T>`的示例: ```java public class Gen<T> { private T t; public Gen(T t) { this.t = t; } public T getT() { return t; } public void setT(T t) { this.t = t; } } ``` 在这个例子中,T代表了我们想要存储的任意类型。当我们创建`Gen`类的实例时,如`Gen<Integer> gen = new Gen<>(1);`,T被替换为Integer,这意味着`Gen`对象现在可以安全地存储和检索Integer类型的值。 2. 通配符(?) 通配符?代表的是未知的类型,但通常有特定的限制。问号可以单独使用,也可以与extends或super关键字结合,以限制通配符的类型范围。例如,`List<? extends Number>`表示列表可以包含任何Number的子类,而`List<? super Integer>`则表示列表可以包含Integer或其超类。 ```java public static void addNumbers(List<? extends Number> numbers) { // 只能调用无参数的方法,不能添加元素 for (Number n : numbers) { System.out.println(n); } } public static void removeNumbers(List<? super Integer> numbers) { // 只能调用无参数的方法,不能获取元素 numbers.remove(new Integer(1)); } ``` 在这两个方法中,由于问号的使用,我们无法向列表中添加元素(因为不知道确切类型),但可以读取(extends)或修改(super)列表内容,前提是操作不会改变列表中的元素类型。 3. 区别 - **灵活性**:类型参数(T)提供最大的灵活性,因为它允许我们指定任意类型,而通配符(?)通常受到某种限制。 - **安全性**:泛型通过类型参数提供更强的类型检查,确保类型安全,而使用通配符可能会限制某些操作,以避免潜在的类型不匹配问题。 - **操作范围**:类型参数允许我们创建、修改和访问对象,而通配符可能只允许读取或写入操作,取决于问号前的extends或super关键字。 - **重用性**:泛型类和方法可以通过不同的类型参数多次实例化,每个实例都有自己的类型约束。通配符主要用于方法参数,允许更广泛的输入类型,但不创建新的类型实例。 总结,类型参数T和通配符?在Java泛型中各有用途,T用于定义具体的类型参数,提供类型安全和重用,而?用于放宽类型限制,增强方法的通用性。理解这两者的区别和应用场景对于编写高效、安全的Java代码至关重要。