当前位置: 首页 > news >正文

Java中泛型的详细介绍

引言:

        Java语言中的泛型是一种强大的特性,它允许我们在编写代码时指定类、接口和方法的参数类型。通过使用泛型,我们可以提高代码的重用性、可读性和安全性。在本博客中,我们将详细介绍Java中泛型的知识。

一、泛型的基本概念

        泛型是Java 5中引入的一个新特性。它的核心思想是参数化类型,即允许在创建类、接口和方法时使用参数来代替具体的类型。这样一来,使用泛型的代码可以适应不同的数据类型,提高代码的灵活性。

二、泛型类与泛型接口

1、定义泛型类

        在泛型类中,我们可以使用泛型来代替具体的类型。例如,我们可以创建一个泛型类Box<T>,其中T表示类型参数,可以是任意合法的Java类型。定义泛型类的语法如下:

public class Box<T> {private T value;public void setValue(T value) {this.value = value;}public T getValue() {return value;}
}

在使用泛型类时,我们可以通过实例化时指定类型参数的方式创建对象:

Box<Integer> box = new Box<>();
box.setValue(10);
Integer value = box.getValue();

通过这种方式,我们可以使用Box类来存储不同类型的对象,而无需创建多个不同的类。

2、定义泛型接口

与泛型类类似,我们也可以定义泛型接口。例如,我们可以创建一个泛型接口List<T>,其中T表示类型参数。定义泛型接口的语法如下:

public interface List<T> {void add(T element);T get(int index);
}

在实现泛型接口时,我们可以指定具体的类型参数:

public class ArrayList<T> implements List<T> {// 省略实现
}

三、泛型方法

        除了泛型类和泛型接口,Java还支持泛型方法。我们可以在方法声明中使用类型参数,从而使该方法可以接受不同的参数类型。定义泛型方法的语法如下:

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

在调用泛型方法时,编译器会根据参数的类型推断出相应的类型参数:

Integer[] numbers = {1, 2, 3, 4, 5};
printArray(numbers);String[] names = {"Alice", "Bob", "Charlie"};
printArray(names);

四、通配符

在使用泛型时,有时我们需要限制类型参数的范围。Java提供了通配符(Wildcard)来实现这个目的。通配符分为无界通配符"?“和有界通配符”?"。

1、无界通配符(Unbounded Wildcard)

无界通配符表示可以是任意类型,使用"?"表示。例如,List<?>表示一个不确定类型的列表。无界通配符通常用于处理一些与类型无关的操作。

2、有界通配符(Bounded Wildcard)

有界通配符用来限制类型参数的范围,可以是上界(Upper Bounded)或下界(Lower Bounded)。例如,List<? extends Number>表示一个元素为任意Number类型或其子类的列表。有界通配符通常用于处理一些与特定类型相关的操作。

五、泛型类型的类型擦除

在编译期间,Java对泛型做了类型擦除。也就是说,泛型类型的参数信息在运行时是不可用的。这意味着无法在运行时获取泛型类型的具体参数。

六、泛型的优点与缺点

1、优点

  • 提高代码的重用性:通过泛型,我们可以编写与特定类型无关的通用代码,从而提高代码的重用性。
  • 增强代码的可读性:使用泛型可以使代码更加清晰和易读,因为类型参数提供了对代码的更好的描述。
  • 提高代码的安全性:泛型可以在编译时捕获一些类型错误,从而减少在运行时出现类型转换错误的可能性。
  • 避免了强制类型转换:在使用非泛型的旧代码中,我们经常需要进行强制类型转换,而泛型可以避免这种情况的发生。

2、缺点

  • 无法使用基本数据类型作为类型参数:由于类型擦除的原因,无法使用基本数据类型(例如int、char等)作为泛型类型的参数。需要使用对应的包装类(如Integer、Character)来代替。
  • 泛型信息在运行时不可用:在泛型代码中,类型参数的具体信息在运行时是无法获得的,这可能导致一些限制和不便。

七、泛型在集合框架中的应用

        Java集合框架中广泛使用了泛型,使得我们可以更安全和方便地操作和管理数据集合。例如,List<E>、Set<E>和Map<K, V>等接口和类都使用泛型来指定其元素类型或键值对类型。

八、泛型的一些常见用法

1、定义泛型类、接口和方法:通过使用类型参数来实现通用代码和数据结构。

泛型类:

public class Box<T> {private T item;public void setItem(T item) {this.item = item;}public T getItem() {return item;}
}// 使用泛型类
Box<Integer> integerBox = new Box<Integer>();
integerBox.setItem(10);
Integer value = integerBox.getItem(); // 返回 10Box<String> stringBox = new Box<String>();
stringBox.setItem("Hello");
String message = stringBox.getItem(); // 返回 "Hello"

泛型接口: 

public interface List<T> {void add(T item);T get(int index);
}// 实现泛型接口
public class ArrayList<T> implements List<T> {private T[] array;public ArrayList() {array = (T[]) new Object[10];}@Overridepublic void add(T item) {// 添加元素到数组}@Overridepublic T get(int index) {// 获取指定位置的元素return array[index];}
}

泛型方法: 

public <T> T getMax(T[] array) {T max = array[0];for (int i = 1; i < array.length; i++) {if (array[i].compareTo(max) > 0) {max = array[i];}}return max;
}// 使用泛型方法
Integer[] numbers = {5, 10, 3, 8};
Integer maxNumber = getMax(numbers); // 返回 10String[] names = {"Alice", "Bob", "Caroline"};
String maxName = getMax(names); // 返回 "Caroline"

2、使用通配符扩展泛型类型的范围:通过使用extends关键字限制类型参数的上界,或使用super关键字限制类型参数的下界。

限制类型参数的上界(extends):

public void processList(List<? extends Number> list) {// 可以读取列表中的元素,因为列表中的元素都是Number或Number的子类for (Number num : list) {// 处理元素}
}List<Integer> integers = new ArrayList<>();
integers.add(10);
integers.add(20);
processList(integers);List<Double> doubles = new ArrayList<>();
doubles.add(3.14);
doubles.add(2.718);
processList(doubles);

限制类型参数的下界(super): 

public void addNumbers(List<? super Integer> list) {// 可以向列表中添加Integer类型的元素,因为列表中的元素类型是Integer或Integer的父类list.add(10);list.add(20);
}List<Number> numbers = new ArrayList<>();
numbers.add(3.14);
addNumbers(numbers);List<Object> objects = new ArrayList<>();
objects.add("Hello");
addNumbers(objects);

3、泛型类型的参数和返回值:可以将泛型类型作为方法的参数和返回值,从而实现对不同类型的支持。

public class GenericExample {// 泛型类型参数作为方法参数public static <T> void printArray(T[] array) {for (T element : array) {System.out.print(element + " ");}System.out.println();}// 泛型类型参数作为方法返回值public static <T> T getFirstElement(T[] array) {if (array != null && array.length > 0) {return array[0];} else {return null;}}public static void main(String[] args) {Integer[] intArray = {1, 2, 3, 4, 5};String[] strArray = {"Hello", "World"};// 使用泛型类型参数作为方法参数printArray(intArray);printArray(strArray);// 使用泛型类型参数作为方法返回值Integer firstInt = getFirstElement(intArray);String firstStr = getFirstElement(strArray);System.out.println("First integer: " + firstInt);System.out.println("First string: " + firstStr);}
}

上述示例中的printArray方法使用了泛型类型参数T[]作为参数,可以接受任意类型的数组,并打印数组中的元素。

getFirstElement方法则使用了泛型类型参数T作为返回值,它返回数组的第一个元素。根据传入的具体数组类型,返回对应类型的元素。

main方法中,我们分别使用了IntegerString类型的数组来演示这两个方法的使用。

总结:
        本博客详细介绍了Java中泛型的知识,包括泛型的基本概念、泛型类与泛型接口、泛型方法、通配符、泛型类型的类型擦除等内容。同时,还介绍了泛型在集合框架中的应用以及一些常见的泛型用法。通过学习和应用泛型,我们可以提高代码的重用性、可读性和安全性,使我们的代码更具灵活性和扩展性。

相关文章:

Java中泛型的详细介绍

引言&#xff1a; Java语言中的泛型是一种强大的特性&#xff0c;它允许我们在编写代码时指定类、接口和方法的参数类型。通过使用泛型&#xff0c;我们可以提高代码的重用性、可读性和安全性。在本博客中&#xff0c;我们将详细介绍Java中泛型的知识。 一、泛型的基本概念 泛型…...

chrome 307状态码

问题&#xff1a;不知道什么原因导致http请求chrome始终307跳转到https,这个307的跳转非常恶心的地方是客户端缓存行为&#xff0c;并且非普通的f12下面清除缓存可以去掉 解决办法&#xff1a;使用chrome的清除浏览数据&#xff0c;通过这个方式清除&#xff0c;才能解决。 问…...

Redis在Windows10中安装和配置

1.首先去下载Redis 这里不给出下载地址&#xff0c;自己可以用去搜索一下地址 下载 下载完成后解压到D盘redis下&#xff0c;本人用的是3.2.100 D:\Redis\Redis-x64-3.2.100 2.解压完成后需要设置环境变量&#xff0c;这里新建一个系统环境变量中path 中添加一个文件所…...

华为OD机试 - 特殊的加密算法(Java JS Python C)

题目描述 有一种特殊的加密算法,明文为一段数字串,经过密码本查找转换,生成另一段密文数字串。 规则如下: 明文为一段数字串由 0~9 组成密码本为数字 0~9 组成的二维数组需要按明文串的数字顺序在密码本里找到同样的数字串,密码本里的数字串是由相邻的单元格数字组成,上…...

MySQL——性能优化与关系型数据库

文章目录 什么是性能&#xff1f;什么是关系型数据库&#xff1f;数据库设计范式 常见的数据库SQL语言结构化查询语言的六个部分版本 MySQL数据库故事历史版本5.6/5.7差异5.7/8.0差异 什么是性能&#xff1f; 吞吐与延迟&#xff1a;有些结论是反直觉的&#xff0c;指导我们关…...

【机器学习300问】12、为什么要进行特征归一化?

当线性回归模型的特征量变多之后&#xff0c;会出现不同的特征量&#xff0c;然而对于那些同是数值型的特征量为什么要做归一化处理呢&#xff1f; 一、为了消除数据特征之间的量纲影响 使得不同指标之间具有可比性。例如&#xff0c;分析一个人的身高和体重对健康的影响&…...

CSV文件中json列的处理2

如上所示&#xff0c;csv文件中包含以中括号{}包含的json字段&#xff0c;可用如下方法提取&#xff1a; import pandas as pd from datetime import date todaystr(date.today()) import jsonfilepath/Users/kangyongqing/Documents/kangyq/202401/调课功能使用统计/ file104…...

eNSP学习——部分VLAN间互通、部分VLAN间隔离、VLAN内用户隔离(MUX-VLAN)

MUX VLAN&#xff08;Multiplex VLAN&#xff09;提供了一种通过VLAN进行网络资源控制 的机制。通过MUX VLAN提供的二层流量隔离的机制可以实现企业内部员 工之间互相通信&#xff0c;而企业外来访客之间的互访是隔离的。 特点&#xff1a; 一、主VLAN端口可以和所有VLAN通信 二…...

【音视频】如何播放rtsp视频流

背景 现阶段直播越来越流行&#xff0c;直播技术发展也越来越快。Webrtc和rtsp是比较火热的技术&#xff0c;而且应用也比较广泛。本文通过实践来展开介绍关于rtsp、webrtc的使用过程。 概要 本文重点介绍如何播放rtsp视频流&#xff0c;通过ffplay方式以及VLC media player…...

Qt6入门教程 8:信号和槽机制(连接方式)

目录 一.一个信号与槽连接的例子 二.第五个参数 1.Qt::AutoConnection 2.Qt::DirectConnection 3.Qt::QueuedConnection 4.Qt::BlockingQueuedConnection 5.Qt::UniqueConnection 三.信号 四.connect函数原型 五.信号与槽的多种用法 六.槽的属性 一.一个信号与槽连接…...

Python如何操作RabbitMQ实现fanout发布订阅模式?有录播直播私教课视频教程

fanout发布订阅模式 基本用法 生产者 import json import rabbitmq# 建立连接 credentials rabbitmq.PlainCredentials(zhangdapeng,zhangdapeng520, ) # mq用户名和密码 connection_target rabbitmq.ConnectionParameters(host127.0.0.1,port5672,virtual_host/,credent…...

QT 原生布局和QML的区别

一、QML 与 Qt Quick的区别 1.1 从概念上区分 为了更精确地对两者进行说明&#xff0c;先看助手对 QML 的描述&#xff1a; QML is a user interface specification and programming language. QML 是一种用户界面规范和标记语言&#xff0c;允许开发人员和设计师创建高性能、流…...

视频转码实例:把MP4转为MKV视频,一键批量转换的操作方法

在数字媒体时代&#xff0c;视频格式的多样性是不可避免的。经常把MP4格式的视频转换为MKV格式。MKV格式有较高的音频和视频质量&#xff0c;能在其他设备或软件上播放视频。以下是云炫AI智剪如何把MP4视频转为MKV格式的一键批量转换操作方法。 已转码的mkv视频效果缩略图展示…...

异步Merkle Tree

1. 引言 前序博客&#xff1a; 利用多核的Rust快速Merkle tree Anoushk Kharangate 2023年论文《Asynchronous Merkle Trees》&#xff0c;其对Merkle tree数据结构进行修改&#xff0c;使得可跨多线程异步计算。 开源代码实现见&#xff1a; https://github.com/anoushk1…...

7. UE5 RPG修改GAS的Attribute的值

前面几节文章介绍了如何在角色身上添加AbilitySystemComponent和AttributeSet。并且还实现了给AttributeSet添加自定义属性。接下来&#xff0c;实现一下如何去修改角色身上的Attribute的值。 实现拾取药瓶回血功能 首先创建一个继承于Actor的c类&#xff0c;actor是可以放置到…...

Oracle/DM序列基本使用

序列(SEQUENCE)是序列号生成器&#xff0c;可以为表中的行自动生成序列号&#xff0c;产生一组等间隔的数值(类型为数字)。其主要的用途是生成表的主键值&#xff0c;可以在插入语句中引用&#xff0c;也可以通过查询检查当前值&#xff0c;或使序列增至下一个值。序列是一个计…...

校验ChatGPT 4真实性的三个经典问题:提供免费测试网站快速区分 GPT3.5 与 GPT4

现在已经有很多 ChatGPT 的套壳网站&#xff0c;以下分享验明 GPT-4 真身的三个经典问题&#xff0c;帮助你快速区分套壳网站背后到底用的是 GPT-3.5 还是 GPT-4。 大家可以在这个网站测试&#xff1a;https://ai.hxkj.vip&#xff0c;免登录可以问三条&#xff0c;登录之后无限…...

概率论与数理统计————3.随机变量及其分布

一、随机变量 设E是一个随机试验&#xff0c;S为样本空间&#xff0c;样本空间的任意样本点e可以通过特定的对应法则X&#xff0c;使得每个样本点都有与之对应的数对应&#xff0c;则称XX&#xff08;e&#xff09;为随机变量 二、分布函数 分布函数&#xff1a;设X为随机变量…...

掌握单例模式的极致挑战:能否默写饿汉式代码?

目录 1.前言 2.本质 3.代码默写 1.前言 在面试中&#xff0c;理解和掌握单例模式是非常重要的。本文旨在帮助读者深入理解饿汉式单例模式&#xff0c;并通过简洁明了的解释和示例代码&#xff0c;使读者能够轻松掌握并默写出饿汉式单例模式的代码实现。 2.本质 饿汉式单例模…...

力扣刷MySQL-第三弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...