Java 中的泛型讲解与使用(超全详解)

news2025/2/25 9:27:32

Java 中的泛型(超全详解)

在 Java 编程中,泛型是一种强大的特性,它允许我们编写可以处理多种数据类型的代码,从而提高代码的复用性和安全性。本文将对 Java 中的泛型进行超全详解,包括泛型的基本概念、基本用法、通配符、泛型方法、类型擦除以及实际应用示例,帮助你全面掌握泛型的使用。

一、泛型的基本概念

1. 什么是泛型?

泛型是 Java SE 5 引入的一种特性,它允许我们在编译时指定类型参数,从而避免在运行时进行类型转换和类型检查。泛型的本质是在编译时进行类型检查,确保类型安全。

2. 为什么使用泛型?

在没有泛型之前,我们通常使用 Object 类型来表示集合中的元素,然后在使用时进行类型转换。这种方式容易导致类型转换异常和代码不安全。泛型的引入解决了这些问题,它可以在编译时进行类型检查,避免类型转换异常,提高代码的安全性和可读性。

二、泛型的基本用法

1. 泛型类

泛型类是在类定义时使用类型参数的类。例如,ArrayList 是一个泛型类,它可以存储任意类型的对象。

示例代码
import java.util.ArrayList;

public class GenericClassExample {
    public static void main(String[] args) {
        // 创建一个泛型类的实例
        ArrayList<String> list = new ArrayList<>();
        // 添加元素
        list.add("Hello");
        list.add("World");
        // 遍历元素
        for (String s : list) {
            System.out.println(s);
        }
    }
}

2. 泛型接口

泛型接口是在接口定义时使用类型参数的接口。例如,Comparable 是一个泛型接口,它可以用于定义对象的排序规则。

示例代码
import java.util.ArrayList;
import java.util.Collections;

public class GenericInterfaceExample {
    public static void main(String[] args) {
        // 创建一个泛型接口的实现类
        ArrayList<String> list = new ArrayList<>();
        list.add("Banana");
        list.add("Apple");
        list.add("Cherry");
        // 排序
        Collections.sort(list);
        // 遍历元素
        for (String s : list) {
            System.out.println(s);
        }
    }
}

3. 泛型方法

泛型方法是在方法定义时使用类型参数的方法。例如,Arrays.asList 是一个泛型方法,它可以将数组转换为列表。

示例代码
import java.util.Arrays;
import java.util.List;

public class GenericMethodExample {
    public static void main(String[] args) {
        // 创建一个数组
        String[] array = {"Hello", "World"};
        // 使用泛型方法将数组转换为列表
        List<String> list = Arrays.asList(array);
        // 遍历元素
        for (String s : list) {
            System.out.println(s);
        }
    }
}

三、通配符

在使用泛型时,我们有时需要处理未知类型的集合。这时可以使用通配符 ? 来表示未知类型。

1. 无界通配符

无界通配符 ? 表示未知类型,可以用于读取集合中的元素,但不能用于添加元素。

示例代码
import java.util.ArrayList;

public class WildcardExample {
    public static void main(String[] args) {
        // 创建一个泛型类的实例
        ArrayList<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("World");
        // 使用无界通配符读取元素
        printList(list);
    }

    public static void printList(List<?> list) {
        for (Object s : list) {
            System.out.println(s);
        }
    }
}

2. 有界通配符

有界通配符 ? extends T 表示未知类型是 TT 的子类,? super T 表示未知类型是 TT 的父类。

示例代码
import java.util.ArrayList;

public class BoundedWildcardExample {
    public static void main(String[] args) {
        // 创建一个泛型类的实例
        ArrayList<Animal> list = new ArrayList<>();
        list.add(new Dog());
        list.add(new Cat());
        // 使用有界通配符读取元素
        printList(list);
    }

    public static void printList(List<? extends Animal> list) {
        for (Animal animal : list) {
            System.out.println(animal);
        }
    }
}

class Animal {
    public String toString() {
        return "Animal";
    }
}

class Dog extends Animal {
    public String toString() {
        return "Dog";
    }
}

class Cat extends Animal {
    public String toString() {
        return "Cat";
    }
}

四、类型擦除

类型擦除是泛型实现的一个重要概念。在编译时,泛型类型信息会被擦除,只保留原始类型。这意味着在运行时,泛型类型信息是不可用的。

1. 类型擦除的影响

类型擦除会导致一些问题,例如无法在运行时获取泛型类型信息,无法使用反射获取泛型类型参数等。

2. 解决方法

为了解决类型擦除的问题,可以使用 Class 类来获取类型信息,或者使用 Type 接口来获取泛型类型参数。

示例代码
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class TypeErasureExample {
    public static void main(String[] args) {
        // 获取泛型类型参数
        Type type = new ArrayList<String>() {}.getClass().getGenericSuperclass();
        ParameterizedType parameterizedType = (ParameterizedType) type;
        Type[] typeArguments = parameterizedType.getActualTypeArguments();
        System.out.println("泛型类型参数: " + typeArguments[0]);
    }
}

五、实际应用示例

1. 泛型在集合框架中的应用

泛型在 Java 的集合框架中得到了广泛应用,例如 ArrayListHashMap 等。

示例代码
import java.util.ArrayList;
import java.util.HashMap;

public class GenericInCollectionExample {
    public static void main(String[] args) {
        // 使用泛型的 ArrayList
        ArrayList<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("World");
        // 使用泛型的 HashMap
        HashMap<String, Integer> map = new HashMap<>();
        map.put("One", 1);
        map.put("Two", 2);
        // 遍历集合
        for (String s : list) {
            System.out.println(s);
        }
        for (String key : map.keySet()) {
            System.out.println(key + ": " + map.get(key));
        }
    }
}

2. 泛型在自定义类中的应用

我们可以在自定义类中使用泛型,从而提高代码的复用性和安全性。(点击链接跳转见详情)
java泛型在自定义类中的应用-CSDN博客

六、总结

通过本文的介绍,我们全面了解了 Java 中泛型的基本概念、基本用法、通配符、泛型方法、类型擦除以及实际应用示例。泛型是 Java 编程中一个重要的特性,它可以在编译时进行类型检查,提高代码的安全性和可读性。希望本文的内容能够帮助你更好地理解和使用泛型,从而提高你的编程水平。

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

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

相关文章

星环科技推出DeepSeek全场景解决方案:即开即用、企业级部署、端侧智能三位一体

星环科技&#xff08;688031.SH&#xff09;正式发布DeepSeek全场景解决方案&#xff0c;全面覆盖个人用户、企业客户及行业场景需求&#xff0c;为用户提供从个人到企业、从云端到本地的全方位AI应用支持&#xff0c;为不同需求的用户提供了灵活、高效且安全的AI解决方案。 省…

《全星质量管理 QMS 软件系统》:赋能企业高效质量管理

《全星质量管理 QMS 软件系统》&#xff1a;赋能企业高效质量管理 在当今竞争激烈的商业环境中&#xff0c;《全星质量管理 QMS 软件系统》脱颖而出&#xff0c;展现出了显著且无可比拟的应用优势。 首先&#xff0c;《全星质量管理 QMS 软件系统》犹如一张严密的质量管控大网…

【多模态处理篇三】【DeepSeek语音合成:TTS音色克隆技术揭秘】

最近帮某明星工作室做AI语音助手时遇到魔幻需求——要求用5秒的咳嗽声克隆出完整音色!传统TTS系统直接翻车,生成的语音像得了重感冒的电音怪物。直到祭出DeepSeek的TTS音色克隆黑科技,才让AI语音从"机器朗读"进化到"声临其境"。今天我们就来扒开这个声音…

C++Qt学习笔记——实现一个串口通信界面

CQt学习笔记——实现一个串口通信界面 一.界面二、项目结构三、头文件1. 文件头部2. 类定义3. 构造函数和析构函数4. 成员函数5. 成员变量 四、代码解析ReceiveAeraInit 函数解析SerialHelper 构造函数解析1. 为什么有两个 SerialHelper&#xff1f;2. 为什么用 :: 和 :&#x…

Word(2010)排版技巧

设置标题样式 选择需要设置的标题 如下图所示。选择文字后&#xff0c;点击对应的样式即可设置。 设置标题格式 设置字体格式 设置段落格式 显示所有样式 标题样式展示 建议 建议新建一个正文样式&#xff0c;可以命名为正文1&#xff0c;因为所有的样式参考的“样式基准…

一.Vue中的条件渲染

1.在<head>中引用 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> 2.在<body>中写入 <div id"app"><p><a v-if "user.usernameadmin"href"#">编辑</a><a …

IO进程 day05

IO进程 day05 9. 进程9. 9. 守护进程守护进程的特点守护进程创建步骤 10. 线程10.1. 线程的概念10.2. 进程和线程的区别10.2. 线程资源10.3. 线程的函数接口1. pthread_create-创建线程线程函数和普通函数的区别 2. pthread_exit3.线程资源回收函数join和detach的区别 获取线程…

【HeadFirst系列之HeadFirstJava】第6天之认识Java的API:解锁高效开发的钥匙

认识Java的API&#xff1a;解锁高效开发的钥匙 在《Head First Java》的第六章节中&#xff0c;作者深入探讨了Java的API&#xff08;Application Programming Interface&#xff09;&#xff0c;并强调了它在Java开发中的重要性。Java API 是Java开发工具包&#xff08;JDK&a…

4 - AXI GPIO按键控制LED实验

文章目录 1 实验任务2 系统框图3 软件设计 1 实验任务 本实验任务是通过调用PL端AXI GPIO IP核&#xff0c;使用中断机制&#xff0c;实现PL端按键控制 PS端LED的功能。 2 系统框图 3 软件设计 注意事项&#xff1a; AXI GPIO IP核是双沿触发中断&#xff0c;不可设置&…

题海拾贝:扫雷

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

Deepseek本地部署小实践(c盘)

目录 前言 一、安装ollama 二、打开终端执行run 三、可视化 前言 小鲸鱼出来以后看到很多大佬本地部署AI&#xff0c;自己也想试一试&#xff0c;第一次部署AI&#xff0c;选了一个简单的办法&#xff0c;实践一下&#xff0c;写得比较粗糙。 一、安装ollama 先简单的介绍…

详细解析d3dx9_27.dll丢失怎么办?如何快速修复d3dx9_27.dll

运行程序时提示“d3dx9_27.dll文件缺失”&#xff0c;通常由DirectX组件损坏或文件丢失引起。此问题可通过系统化修复方法解决&#xff0c;无需重装系统或软件。下文将详细说明具体步骤及注意事项。 一.d3dx9_27.dll缺失问题的本质解析 当系统提示“d3dx9_27.dll丢失”时&…

【LeetCode刷题之路】leetcode155.最小栈

LeetCode刷题记录 &#x1f310; 我的博客主页&#xff1a;iiiiiankor&#x1f3af; 如果你觉得我的内容对你有帮助&#xff0c;不妨点个赞&#x1f44d;、留个评论✍&#xff0c;或者收藏⭐&#xff0c;让我们一起进步&#xff01;&#x1f4dd; 专栏系列&#xff1a;LeetCode…

Vue全局变量的定义和使用,创建 Store变量、读取、修改

在VUE中&#xff0c;当需要各js、各页面都能读写的全局变量时&#xff0c;可以用store变量&#xff0c;从定义到使用的方法如下 一&#xff0e;定义变量&#xff0c;例&#xff1a;我们定一个全局变量gxh 找到 vue的/ src/ store路径, 在 modules文件夹下创建文件gvar.js 在…

基于Docker的前端环境管理:从开发环境到生产部署的实现方案

# 基于Docker的前端环境管理&#xff1a;从开发环境到生产部署的实现方案 简介及前端开发环境挑战 简介 是一种容器化平台&#xff0c;可以将应用程序及其依赖项打包为一个容器&#xff0c;提供一种轻量级、可移植的环境。它能够简化开发、部署和运维的流程&#xff0c;提高…

单片机延时函数怎么写规范?

我们以前在开发产品的时候&#xff0c;肯定会碰到一些延时需求&#xff0c;比如常见的LED闪烁&#xff0c;按键消抖&#xff0c;控制IO口输出时序等等。 别小看延时&#xff0c;这个小问题&#xff0c;想做好&#xff0c;甚至要考虑到程序架构层面。 在开发板上&#xff0c;可能…

数据结构 1-2 线性表的链式存储-链表

1 原理 顺序表的缺点&#xff1a; 插入和删除移动大量元素数组的大小不好控制占用一大段连续的存储空间&#xff0c;造成很多碎片 链表规避了上述顺序表缺点 逻辑上相邻的两个元素在物理位置上不相邻 头结点 L&#xff1a;头指针 头指针&#xff1a;链表中第一个结点的存储…

vue2版本elementUI的table分页实现多选逻辑

1. 需求 我们需要在表格页上实现多选要求&#xff0c;该表格支持分页逻辑。 2. 认识属性 表格属性 参数说明类型可选值默认值data显示的数据array——row-key行数据的 Key&#xff0c;用来优化 Table 的渲染&#xff1b;在使用 reserve-selection 功能与显示树形数据时&…

设计模式-解释器模式、装饰器模式

解释器模式 定义 给分析对象定义一个语言&#xff0c;并定义语言的文法表示&#xff0c;再设计一个解释器来解释语言中的句子。也就是说&#xff0c;用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口&#xff0c;该接口解释一个特定的上下文。 类图 …

linux 命令+相关配置记录(持续更新...)

linux 命令记录相关配置记录 磁盘切换 cd D&#xff1a;#这里表示切换到D盘查看wsl 安装的linux 子系统 wsl --list -vwsl 卸载 linux 子系统 wsl --unregister -xxx # xxx 表示子系统的名字备份Linux 子系统 导出 wsl --export xxx yyy # xxx 表示子系统的名字 yyy 表示压…