Java泛型是什么?有什么作用?

devtools/2025/3/16 17:43:07/

Java泛型(Generics)是Java语言中一种类型参数化的机制,允许在类、接口、方法中使用类型参数,使代码能够处理多种数据类型,同时保证类型安全。泛型的主要目的是增强代码的复用性安全性,避免类型转换错误。

泛型的核心概念

  • 类型参数化
    在定义类、接口或方法时,用<T>、<K,V>等形式声明类型参数,实际使用时再指定具体类型。

    java">// 泛型类
    public class Box<T> {private T content;public void setContent(T content) { this.content = content; }public T getContent() { return content; }
    }// 使用
    Box<String> stringBox = new Box<>();
    stringBox.setContent("Hello");
    String value = stringBox.getContent(); // 无需强制类型转换
    
  • 类型安全
    编译器会检查泛型类型的合法性,防止在集合中混入不兼容的类型。

    java">List<String> list = new ArrayList<>();
    list.add("Java");
    // list.add(100); // 编译报错:类型不匹配
    

泛型的作用

  1. 类型安全(Type Safety)
    在编译阶段进行类型检查,避免运行时出现ClassCastException

    java">// 不使用泛型(存在风险)
    List list = new ArrayList();
    list.add("Java");
    list.add(100); // 编译通过,但运行时会出错
    String s = (String) list.get(1); // 运行时抛出ClassCastException// 使用泛型(类型安全)
    List<String> safeList = new ArrayList<>();
    safeList.add("Java");
    // safeList.add(100); // 编译直接报错
    
  2. 消除强制类型转换
    从集合中获取元素时,无需显式强制转换。

    java">List<String> names = new ArrayList<>();
    names.add("Alice");
    String name = names.get(0); // 直接返回String类型
    
  3. 代码复用
    通过泛型类、泛型方法,编写可处理多种类型的通用代码。

    java">public static <T> T getFirstElement(List<T> list) {return list.get(0);
    }
    // 支持任何类型的List
    String s = getFirstElement(Arrays.asList("A", "B"));
    Integer n = getFirstElement(Arrays.asList(1, 2));
    
  4. 增强可读性
    泛型让代码的意图更明确。例如,Map<String, Integer>直接表明键是String,值是Integer。

泛型的核心特性

  1. 类型擦除(Type Erasure)
    Java泛型在编译后会被擦除,转换为原始类型(Raw Type),并在必要时插入强制类型转换。

    java">// 编译前
    List<String> list = new ArrayList<>();
    // 编译后(类型擦除)
    List list = new ArrayList();
    
  2. 通配符(Wildcards)
    (1)使用?表示未知类型,解决泛型类型的灵活性问题。
    (2)上界通配符(<? extends T>):接受T及其子类。
    (3)下界通配符(<? super T>):接受T及其父类。

    java">// 上界通配符:可以读取,不能写入
    List<? extends Number> numbers = new ArrayList<Integer>();
    Number num = numbers.get(0); // 允许读取
    // numbers.add(10); // 编译报错// 下界通配符:可以写入,读取为Object
    List<? super Integer> list = new ArrayList<Number>();
    list.add(100); // 允许写入
    Object obj = list.get(0); // 读取为Object
    
  3. 泛型边界(Bounded Type)
    通过 “T extends SomeClass” 限制泛型类型的范围。

    java">public class Calculator<T extends Number> {public double sum(T a, T b) {return a.doubleValue() + b.doubleValue();}
    }
    // 只能使用Number及其子类(如Integer、Double)
    Calculator<Integer> intCalc = new Calculator<>();
    

泛型的典型应用场景

  • 集合框架(Collections)
    List、Map<K,V>等集合类均使用泛型,确保元素类型安全。

    java">Map<String, Integer> scores = new HashMap<>();
    scores.put("Alice", 90);
    
  • 工具类(如Optional)
    包装可能为空的值,避免NullPointerException。

    java">Optional<String> name = Optional.ofNullable(getName());
    
  • 函数式接口(如Function<T,R>)
    支持泛型参数和返回值,用于Lambda表达式。

    java">Function<Integer, String> intToString = num -> "Value: " + num;
    

注意事项

  • 泛型不支持基本类型
    必须使用包装类(如List<Integer>,而非List<int>)。

  • 类型擦除的限制
    无法在运行时获取泛型类型信息(如new T()或T.class)。

  • 泛型数组的创建
    直接创建泛型数组是非法的,需通过反射或强制转换。

总结

Java泛型通过类型参数化,提供了一种类型安全的编程方式,避免了强制类型转换的繁琐和潜在错误,同时提升了代码的可读性和复用性。尽管存在类型擦除等限制,泛型仍是Java开发中不可或缺的核心特性。


http://www.ppmy.cn/devtools/167612.html

相关文章

【Tools】Visual Studio Code安装保姆级教程(2025版)

00. 目录 文章目录 00. 目录01. Visual Studio Code概述02. Visual Studio Code下载03. Visual Studio Code安装04. Visual Studio Code配置05. 附录 01. Visual Studio Code概述 Visual Studio Code&#xff08;简称 VS Code&#xff09;是由微软开发的一款免费、开源且跨平台…

每日一题---数组中两个字符串的最小距离

数组中两个字符串的最小距离 给定一个字符串数组strs&#xff0c;再给定两个字符串str1和str2&#xff0c;返回在strs中str1和str2的最小距离&#xff0c;如果str1或str2为null&#xff0c;或不在strs中&#xff0c;返回-1。 链接&#xff1a;数组中两个字符串的最小距离__牛…

MySQL 8 主从同步安装与配置

拟机&#xff0c;由 CentOS 换成了 Ubuntu&#xff0c;用 Xteminal 连接之后&#xff0c;为了方便改配置文件&#xff0c;把文件权限改成 666 了&#xff0c;结果因为这个调半天&#xff0c;一直以为是网络问题或者是配置问题。要注意为了防止配置文件被未经授权的用户修改&…

STM32 单片机常见的 8 种输入输出模式

STM32 单片机常见的 8 种输入输出模式 文章目录 STM32 单片机常见的 8 种输入输出模式1. 浮空输入模式 (GPIO_Mode_IN_FLOATING)介绍使用场景示例代码 2. 上拉输入模式 (GPIO_Mode_IPU)介绍使用场景示例代码 3. 下拉输入模式 (GPIO_Mode_IPD)介绍使用场景示例代码 4. 模拟输入模…

拥有一台云服务器能做什么呢?

拥有一台云服务器就像拥有了一台24小时在线的远程电脑&#xff0c;你可以通过互联网随时随地管理它。它的用途非常广泛&#xff0c;无论是个人学习、开发测试&#xff0c;还是企业级应用部署&#xff0c;都能发挥重要作用。以下是常见的应用场景&#xff0c;按需求分类整理&…

SwanLab私有化部署教程!

SwanLab私有化部署版面向所有个人用户免费开放&#xff0c;部署方案基于Docker Compose&#xff0c;能非常轻松地部署在 Windows/MacOS/Linux 机器上&#xff0c;希望能成为各位训练师的独门炼丹利器。 下面我们会介绍一下如何安装私有化部署版。 1. SwanLab介绍 SwanLab 是…

Unity 封装一个依赖于MonoBehaviour的计时器(上) 基本功能

灵感来自下面这本书的协程部分,因此我就自己尝试写了一个 我的新书Unity3D游戏开发&#xff08;第3版&#xff09; | 雨松MOMO程序研究院 如果你不知道什么是协程:unity保姆级教程之协同程序_unity协同-CSDN博客 一句话概括:协程就是单线程的异步操作,其作用于Unity的主线程 1…

如何在github上参与开源项目

1. 创建 GitHub 账号 如果你还没有 GitHub 账号&#xff0c;首先需要注册一个&#xff1a; 访问 GitHub 官网。 点击右上角的“Sign up”按钮&#xff0c;填写注册信息并完成注册。 2. 找到感兴趣的项目 GitHub 上有成千上万的开源项目&#xff0c;你可以通过以下方式找到感兴趣…