Java泛型的一些细节

泛型的核心思想是将类型参数化

泛型主要目的是提供类型安全和消除类型转换,从而使代码更加健壮和可读。它允许在定义接口、方法属性时使用类型参数。

注意:

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  
    }  
}  

代码说明

  1. printList 方法接受一个 List<?> 参数,意味着该方法可以接受任何类型的列表(如 List<Integer>List<String>等)。

  2. 在方法的实现中,元素被作为 Object 处理,因为具体的类型并不重要。

  3. main 方法中,我们创建了一个 List<Integer> 和一个 List<String>, 然后将它们传递给 printList 方法。

限制

  • 读取元素 :虽然可以读取无界通配符列表中的元素,但只能将其作为 Object 处理。

  • 添加元素 :在无界通配符的情况下,无法向列表中添加任何元素 (除了 null),因为编译器不知道列表接受何种类型的元素。

总结

  • 无界通配符 (<?>) 是一种表示任意类型的通配符,用于那些不关心具体类型的场景。

  • 读取操作 是合法的,但返回的元素类型只能是 Object

  • 写入操作 除了 null 以外是被禁止的。

这种灵活性使得无界通配符在编写与类型无关的代码时非常有用,可以增强代码的复用性和可读性。

上界通配符

  • 定义<? extends T> 表示可以接受 T 或 T 的子类型。它用于限制泛型类型为 T 及其子类。

  • 使用场景 :当你希望只读取数据 ,而不修改数据时(即只对数据进行读取操作),可以使用上界通配符。

  • 示例

    typescript 复制代码
    java
    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 及其父类。

  • 使用场景 :当你希望往集合中添加数据时(即进行写入操作),可以使用下界通配符。

  • 示例

    scss 复制代码
    javapublic 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 或其子类的元素。

通过正确使用上界和下界通配符,可以编写更加灵活和更具可重用性的泛型代码。

相关推荐
猿周LV6 分钟前
JMeter 安装及使用 [软件测试工具]
java·测试工具·jmeter·单元测试·压力测试
晨集8 分钟前
Uni-App 多端电子合同开源项目介绍
java·spring boot·uni-app·电子合同
时间之城10 分钟前
笔记:记一次使用EasyExcel重写convertToExcelData方法无法读取@ExcelDictFormat注解的问题(已解决)
java·spring boot·笔记·spring·excel
椰羊~王小美17 分钟前
LeetCode -- Flora -- edit 2025-04-25
java·开发语言
凯酱25 分钟前
MyBatis-Plus分页插件的使用
java·tomcat·mybatis
程序员总部35 分钟前
如何在IDEA中高效使用Test注解进行单元测试?
java·单元测试·intellij-idea
oioihoii38 分钟前
C++23中if consteval / if not consteval (P1938R3) 详解
java·数据库·c++23
佳腾_1 小时前
【Web应用服务器_Tomcat】一、Tomcat基础与核心功能详解
java·前端·中间件·tomcat·web应用服务器
异常君1 小时前
线程池隐患解析:为何阿里巴巴拒绝 Executors
java·后端·代码规范
Java技术小馆1 小时前
SpringBoot中暗藏的设计模式
java·面试·架构