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

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

相关推荐
肖哥弹架构22 分钟前
图解ArrayList数据结构设计与应用案例
java·后端·程序员
NiNg_1_23431 分钟前
Java爬虫(HttpURLConnection)详解
java·开发语言·爬虫
我来变强了1 小时前
WebSocket简易聊天室实现(有详细解释)
java·网络·websocket
dr李四维1 小时前
深入List集合:ArrayList与LinkedList的底层逻辑与区别
java·数据结构·后端·list
编程修仙1 小时前
java集合—List的底层结构和源码分析
java·开发语言·list
武昌库里写JAVA1 小时前
R语言机器学习与临床预测模型77--机器学习预测常用R语言包
java·开发语言·算法·spring·log4j
response_L1 小时前
PageOffice打开保存文件的执行流程(工作原理)
java·word·excel·在线编辑
旺旺碎冰冰、1 小时前
List、ArrayList与顺序表1
java·开发语言·数据结构·list
YiHanXii1 小时前
Java中 LinkedList<>,ArrayDeque<>的区别 || Queue和Deque的区别
java·算法
桃始笑叶始泪1 小时前
HTML面试题
java·前端·html