什么是 Java 泛型

news2025/4/3 2:40:29

一、什么是 Java 泛型?

泛型(Generics) 是 Java 中一种强大的编程机制,允许在定义类、接口和方法时使用类型参数。通过泛型,可以将数据类型作为参数传递,从而实现代码的通用性和类型安全。

简单来说,泛型让你可以编写更灵活、更通用的代码,同时避免类型转换错误。例如:

// 使用泛型的 List
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
String str = stringList.get(0); // 不需要强制类型转换

如果没有泛型,List 默认存储的是 Object 类型的对象,取出时需要手动进行类型转换,容易出错。


二、泛型的底层原理

Java 泛型的底层实现是基于 类型擦除(Type Erasure) 的。所谓类型擦除,是指编译器在编译阶段会将泛型类型替换为它们的上界(通常是 Object),并在运行时移除泛型信息。这样做的目的是为了兼容旧版本的 Java(Java 5 引入泛型之前)。

示例:
List<String> list = new ArrayList<>();
list.add("Hello");
String s = list.get(0);

经过编译后,实际上是这样的:

List list = new ArrayList();
list.add("Hello");
String s = (String) list.get(0); // 编译器插入了类型转换

因此,泛型在运行时并不存在具体的类型信息,所有泛型相关的操作都是在编译时完成的。

类型擦除的优点和缺点:
  • 优点
    • 向下兼容旧版本的 Java。
    • 减少了运行时的性能开销。
  • 缺点
    • 泛型类型信息在运行时不可用。
    • 无法创建泛型类型的实例(如 new T())。

三、为什么要使用泛型?

  1. 类型安全
    泛型可以在编译时检查类型,避免运行时的 ClassCastException 错误。例如,如果你试图向一个 List<String> 中添加一个 Integer,编译器会直接报错。

  2. 减少类型转换
    使用泛型后,编译器会自动插入必要的类型转换代码,减少了手动类型转换的麻烦。

  3. 提高代码复用性
    泛型可以让代码更加通用,适用于多种数据类型。例如,ArrayList<T> 可以用于存储任何类型的对象。

  4. 增强可读性
    使用泛型后,代码的意图更加明确,例如 List<String> 明确表示这是一个存储字符串的列表。


四、泛型的应用场景

以下是泛型在 Java 中的主要应用场景:

1. 集合类

这是泛型最常见的应用场景。Java 集合框架(如 ListSetMap 等)都支持泛型,使得集合可以存储特定类型的元素。

List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");

for (String name : names) {
    System.out.println(name);
}
2. 自定义泛型类

你可以定义自己的泛型类,使其能够处理多种类型的数据。

public class Box<T> {
    private T item;

    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }
}

// 使用
Box<String> stringBox = new Box<>();
stringBox.setItem("Hello");
String value = stringBox.getItem();
3. 泛型方法

除了泛型类,你还可以定义泛型方法,使方法能够处理多种类型的参数。

public <T> void printArray(T[] array) {
    for (T element : array) {
        System.out.println(element);
    }
}

// 使用
printArray(new Integer[]{1, 2, 3});
printArray(new String[]{"A", "B", "C"});
4. 泛型接口

接口也可以定义为泛型,使其实现类能够指定具体类型。

public interface Container<T> {
    void add(T item);
    T get(int index);
}

public class MyContainer<T> implements Container<T> {
    private List<T> items = new ArrayList<>();

    @Override
    public void add(T item) {
        items.add(item);
    }

    @Override
    public T get(int index) {
        return items.get(index);
    }
}
5. 通配符(Wildcard)详细说明

泛型中的通配符(?)用于表示未知类型,通常用于方法参数或返回值。

  • 无界通配符<?> 表示任意类型。
  • 上界通配符<? extends T> 表示 T 或其子类。
  • 下界通配符<? super T> 表示 T 或其父类。
public void printList(List<?> list) {
    for (Object obj : list) {
        System.out.println(obj);
    }
}

public void addNumbers(List<? super Integer> list) {
    list.add(1);
    list.add(2);
}
6. 泛型与反射

虽然泛型在运行时会被擦除,但可以通过反射获取原始类型信息。

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Class<?> clazz = list.getClass();
        System.out.println(clazz); // 输出:class java.util.ArrayList
    }
}
7. 泛型在设计模式中的应用

许多设计模式(如工厂模式、策略模式等)都可以结合泛型来实现更灵活的设计。

public interface Factory<T> {
    T create();
}

public class StringFactory implements Factory<String> {
    @Override
    public String create() {
        return "Hello";
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2326911.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity中根据文字数量自适应长宽的对话气泡框UI 会自动换行

使用Ugui制作一个可以根据文本数量自动调整宽度,并可以自动换行的文字UI 或者不要独立的Bg,那么一定要把bg的img设置成切片

【小也的Java之旅系列】02 分布式集群详解

文章目录 前言为什么叫小也 本系列适合什么样的人阅读正文单体优点缺点 CAP为什么CAP不可能全部满足&#xff1f;CAP 三选二 分布式事务分布式方案——SeataXA模式&#xff08;强一致&#xff09;AT模式&#xff08;自动补偿&#xff0c;默认模式&#xff09;TCC模式&#xff0…

Ubuntu里安装Jenkins

【方式1】&#xff1a;下载war包&#xff0c;直接运行&#xff0c;需提前搭建Java环境&#xff0c;要求11或17&#xff0c;不推荐&#xff0c;war包下载地址&#xff0c;将war包上传到服务器&#xff0c;直接使用命令启动 java -jar /data/jenkins/jenkins.war【方式2】&#…

C++包管理工具vcpkg的安装使用教程

前言 使用vcpkg可以更方便地安装各种库&#xff0c;省去配置的时间和配置失败的风险&#xff0c;类似python中的anaconda&#xff0c;懒人必备 参考 安装参考&#xff1a;https://bqcode.blog.csdn.net/article/details/135831901?fromshareblogdetail&sharetypeblogde…

微服务面试题:配置中心

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

Qt msvc2017程序无法用enigma vitrual box打包,用winrar打包

我们通常打包Qt程序用Enigma virtual box。这样我们的程序就可以在别的电脑上也能运行&#xff0c;但是有时候&#xff0c;我们发现Enigma virtual box在打包的时候&#xff0c;对于msvc2017需要编译的程序中引用webengineview模块&#xff0c;打包时候发现不能运行。 我们如何…

微服务集成测试 -华为OD机试真题(A卷、JavaScript)

题目描述 现在有n个容器服务&#xff0c;服务的启动可能有一定的依赖性&#xff08;有些服务启动没有依赖&#xff09;&#xff0c;其次&#xff0c;服务自身启动加载会消耗一些时间。 给你一个n n 的二维矩阵useTime&#xff0c;其中useTime[i][i]10表示服务i自身启动加载需…

Mac: 运行python读取CSV出现 permissionError

在MAC机器里&#xff0c;之前一直运行程序在某个指定的目录下读取excel和csv文件&#xff0c;没有出现错误&#xff0c;有一天突然出现错误&#xff1a;permissionError:[Errno 1] Operation not permitted&#xff0c; 具体错误信息如下&#xff1a; 经过调查得知&#xff0c…

UE5 学习笔记 FPS游戏制作30 显示击杀信息 水平框 UI模板(预制体)

文章目录 一制作单条死亡信息框水平框的使用创建一个水平框添加子元素调整子元素顺序子元素的布局插槽尺寸填充对齐 制作UI 根据队伍&#xff0c;设置文本的名字和颜色声明变量 将变量设置为构造参数根据队伍&#xff0c;设置文本的名字和颜色在构造事件中&#xff0c;获取玩家…

西门子TCP通讯过程中硬件连接突然断开

通信原理探秘又结合在工作中遇到的问题,关注到了通讯中的KeepAlive定时器的设置,所以做了如下实验。 硬件: 1513PLC TCP客户端 PC TCP服务器 前提条件:禁用PLC侧KeepAlive 程序: 测试流程: 打开PC端网络调试助手,设置为TCP服务器,打开链接; PC端打开WireShack软…

2025宁德时代测评Verify考什么?网申测评如何通过SHL笔试|附真题线上笔试考点、高分攻略、CATL新能源科技SHL测评宁德社招题目、面试攻略、求职建议

——职小豚 带你拆解新能源巨头招聘密码 一、宁德时代&#xff1a;新能源赛道「超级独角兽」 作为全球动力电池龙头&#xff0c;宁德时代&#xff08;CATL&#xff09;的江湖地位无需多言&#xff1a; 技术硬实力&#xff1a;麒麟电池、钠离子电池、无钴电池等黑科技加持&…

Spring Boot @RequestParam 解析参数时的常见问题及解决方案

1&#xff0c;遇到的问题&#xff1a;将后端接口写完后我想通过PostMan进行简单的测试一下&#xff0c;一不小心就遇到了这样的情况&#xff1a; org.springframework.web.bind.MissingServletRequestParameterException: Required Integer parameter contractId is not prese…

Firefox 浏览器同步一个账户和书签网址

Firefox 浏览器同步一个账户和书签网址 Firefox 支持跨设备接续浏览&#xff0c;可实现电脑、手机与平板无缝衔接。无论您在使用哪台设备上使用 Firefox&#xff0c;都能获取书签、浏览历史、保存的密码等信息。当然也能实现windows、ios、linux、android系统中安装firefox浏览…

Maven多模块项目,其他项目引用子模块的依赖,无法打包,提示没有找到依赖

背景&#xff1a; 微服务项目 每个服务都是单独的项目&#xff0c;会存在依赖关联的问题&#xff0c;在子模块的下面 depoly 之后&#xff0c;就会出现别的项目&#xff0c;无法package 原因&#xff1a; 多模块项目&#xff0c;depoly 需要在父模块下面执行

mediacodec服务启动时加载media_codecs.xml

media.codec服务启动时&#xff0c; 会创建 implementation::Omx 和 implementation::OmxStore&#xff0c; 构造 Omx时&#xff0c; 会解析codec相关的xml文件&#xff0c;一般从会如下目录中&#xff0c; // from getDefaultSearchDirs() { "/product/etc",&quo…

本地部署DeepSeek-R1(Dify压力测试和性能调优)

安装压测软件 为了有效测试&#xff0c;应在局域网设备测试&#xff0c;我这里用的服务器是局域网内的Ubuntu&#xff0c;下载的压测软件是WRK apt install wrk测试脚本 为了省事我直接在/root目录下新建lua脚本 vim test.lua脚本内容如下&#xff0c;app-xxxx更换为你工作…

自动备份文件到服务器,自动备份文件到服务器有哪些方法?

将SQL Server数据库自动备份文件到服务器&#xff0c;可以通过多种方法实现。以下是几种常用的方法&#xff1a; 一、使用SQL Server Management Studio&#xff08;SSMS&#xff09;和SQL Server代理 配置SQL Server代理&#xff1a;确保SQL Server代理服务已启动。如果未启…

Ollama+open-webui搭建私有本地大模型详细教程

Ollamaopen-webui搭建私有本地大模型详细教程 1. 什么是 Ollama&#xff1f; 1.1. Ollama 简介 ​ Ollama 是一个轻量级的 AI 模型运行时&#xff0c;专注于简化 AI 模型的部署和使用。它支持多种预训练模型&#xff08;如 Llama、Vicuna、Dolly 等&#xff09;&#xff0c;…

GPT-4o 原生图像生成技术解析:从模型架构到吉卜力梦境的实现

最近不少 AI 爱好者、设计师、Vlogger 在社交平台晒出了 GPT-4o 生成的梦幻图像&#xff0c;尤其是吉卜力风格的作品——柔和光影、日系构图、治愈色彩、富有情感的角色表达&#xff0c;一下子击中了无数人的“童年回忆 审美舒适区”。 &#x1f3a8; 下面是一些 GPT-4o 实际生…

测试cursor-AI编辑器

Cursor是一个免费的&#xff0c;内置AI插件的编辑器&#xff0c;在vscode基础上开发&#xff0c;可以创建和分析代码&#xff0c;还能提出修改建议。官网是 https://www.cursor.com/cn 载入SFTP的方式跟vscode是一样的&#xff0c;但是会有这样的报错&#xff1a; 报错&#x…