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 或其子类的元素。

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

相关推荐
sg_knight33 分钟前
Spring Cloud与RabbitMQ深度集成:从入门到生产级实战
java·spring boot·spring·spring cloud·消息队列·rabbitmq·stream
Chan161 小时前
批处理优化:从稳定性、性能、数据一致性、健壮性、可观测性五大维度,优化批量操作
java·spring boot·后端·性能优化·java-ee·intellij-idea·优化
行者阿毅1 小时前
langchain4j+DashScope (通义千问)文生图
java·ai作画
Bug退退退1231 小时前
Java 网络流式编程
java·服务器·spring·sse
IT机器猫1 小时前
RabbitMQ
java·rabbitmq·java-rabbitmq
小杨的全栈之路1 小时前
冒泡、插入、选择、归并、堆排序:从名字由来到Java实现,一篇讲透
java·排序算法
yinke小琪2 小时前
面试官:谈谈为什么要拆分数据库?有哪些方法?
java·后端·面试
自由的疯2 小时前
java DWG文件转图片
java·后端·架构
小兔崽子去哪了2 小时前
EasyExcel 使用
java·excel
青云交2 小时前
Java 大视界 -- Java 大数据机器学习模型的对抗攻击与防御技术研究
java·机器学习模型·对抗攻击·java 大数据·防御技术·对抗训练·i - fgsm