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

【Java基础】泛型(一)-基础使用

本文以Java的官方文档为参考,辅以代码示例,尽可能详尽的叙述泛型的每一个特性

什么是泛型

泛型(Generics)也称为参数化类型(parameterized types),也就是将类型本身作为接口、类、方法中的参数,相应地声明泛型接口、泛型类、泛型方法,在具体调用时再传入类型参数。从而实现同一种接口、类、方法适用于不同的类型。

为什么要有泛型

  1. 代码重用

泛型程序设计,意味着代码可以针对不同类型重用,你不可能希望针对String和Integer分别编写一个ArrayList

  1. 编译时类型检查

Java5之前,如果想实现泛型就需要这样做:例如定义一个包含Object数组的ArrayList

List v = new ArrayList();
v.add("test"); // 不会做类型检查
Integer i = (Integer)v.get(0); // 运行时异常(Runtime error)

这里其实利用了多态,编译时对set操作不会做类型检查,也不会报get操作的异常。强转的错误在运行时才会抛异常(向下转型不安全

如果一个错误没有被发现,那么系统会进入不可预知的状态,会产生更严重的后果,并且使得错误更难被发现,所以,一个鲁棒的系统应该尽可能早地和多地报告异常。这个哲学思想也可以叫做“故障导向安全原则”。

java5之后引入泛型,实现方式:加入类型参数,(类型本身作为一个参数),好处在于

  1. 更易读:代码会有很好的可读性,人们就知道ArrayList存的是什么类型
  2. 更安全:而且编译时set的时候会有类型检查,get的时候也不用手工强转了

泛型类

泛型类的声明和使用

假设有一个Box类,我希望可以set和get任意类型的object,在没有泛型机制时的定义如下:

public class Box {private Object object;public void set(Object object) { this.object = object; }public Object get() { return object; }
}

显然,如上节中提到,get方法调用时可能会出现运行时异常,因此我们利用泛型来实现Box类

首先,泛型类的定义格式如下:

class name<T1, T2, ..., Tn>

尖括号中是类型参数,可以被用在类中的任意位置,包括对象类型,方法入参类型,返回值类型。

由此,Box类的定义如下:

public class Box<T> {// T stands for "Type"private T t;public void set(T t) { this.t = t; }public T get() { return t; }
}

可以看出这里就是将原来Object类型全部换成了类型参数T

创建类对象,将T替换为实际的类型参数即可(就像给方法传参一样,将形参T变为实参Integer)

Box<Integer> integerBox = new Box<Integer>();

简化的使用方式:类型推断

Java 7之后可以利用类型推断,省略构造器后面的泛型:

Box<Integer> integerBox = new Box<>();

泛型接口

泛型接口的声明和使用

泛型接口与泛型类的定义大同小异,以一个简化的List接口为例

public interface List<E> {boolean add(E e);E get(int index);
}

实现或者继承泛型接口,有两种情况:

一种是不替换泛型形参E,即不指定具体的类型。这时类名后面必须也把泛型实参添加上,以ArrayList为例

public class ArrayList<E> extends AbstractList<E>implements List<E> { //ArrayList后面必须添加<E>boolean add(E e);E get(int index);
}

另一种就是替换泛型形参E。这时实现类中所有形参出现的地方必须替换为实参,例如我定义了一个只存String类型的StringArrayList

public class StringArrayList extends ArrayList<String> { boolean add(String e); //方法重写String get(int index);
}

泛型方法

泛型方法的声明和使用

泛型方法是带类型参数的方法,注意类型参数在修饰符后面,返回类型前面。

泛型方法的作用范围只在本方法中,因此可以作为方法入参类型,或者返回值类型

典型例子就是Arrays.asList方法(泛型方法其实在Collections, Arrays等工具类中应用的很广泛

public static <T> List<T> asList(T... a) { //这里返回List<T>,其实就相当于T用在了泛型方法的返回值类型中return new ArrayList<>(a);
}

这时如何使用上面的泛型方法?有以下两种:

  1. 替换尖括号内的类型参数(相当于传参
String[] stringArr = new String[]{"abc", "123", "opq"};
List<String> StringList = Arrays.<String>asList(stringArr);
  1. 编译器自行推断 一般我们在使用工具类的泛型方法时基本没见过上面的语法,其实编译器可以通过传入参数进行推断
List<String> StringList = Arrays.asList(stringArr);

注意事项:静态方法使用泛型

上面提到类型形参T可以用在类中的任意位置,但实际上不可以作为静态方法的入参和返回值类型,如果想让静态方法用到泛型,就得让静态方法自身变为泛型方法。

public class Box<T> {//这里Box后面的泛型<T>和静态方法的泛型<T>并不是一个类型public static <T> void show(T t){}
}

相关文章:

【Java基础】泛型(一)-基础使用

本文以Java的官方文档为参考&#xff0c;辅以代码示例&#xff0c;尽可能详尽的叙述泛型的每一个特性 什么是泛型 泛型&#xff08;Generics&#xff09;也称为参数化类型&#xff08;parameterized types&#xff09;&#xff0c;也就是将类型本身作为接口、类、方法中的参数…...

学Python不会不知道NumPy计算包吧,带你五分钟看懂NumPy计算包

从今天我们就开始进入 Python 数据分析工具的教程。 前段时间数据分析和Python都讲了一点点&#xff0c;但是Python的数据库&#xff0c;讲的少了点&#xff0c;所以接下来就讲讲这些重要的常用数据库吧&#xff01;&#xff01;&#xff01; Python 数据分析绝对绕不过的四个…...

积水内涝监测——埋入式积水终端设备介绍

一、设备概述 埋入式积水终端是针对城市内涝推出的积水信息监测采集设备&#xff0c;采用超声波传感技术&#xff0c;对积水的深度进行精确的测量。产品能够在低温、腐蚀环境下可靠运行本产品特别适用于智慧城市中&#xff0c;对城市道路、社区低洼处的积水进行实时监测上报到…...

Kafka的日志同步

首先介绍下LEO和HW LEO&#xff1a; 即LogEndOffset&#xff0c;表示该副本下次日志记录的偏移量HW&#xff1a;即HighWatermark&#xff0c;高水位线&#xff0c;是所有ISR副本集合中的LEO最小值上图中&#xff0c;如果此时三个副本都在ISR集合中&#xff0c;那么此时他们的LE…...

【Mybatis源码解析】mapper实例化及执行流程源码分析

文章目录简介环境搭建源码解析基础环境&#xff1a;JDK17、SpringBoot3.0、mysql5.7 储备知识&#xff1a;《【Spring6源码・AOP】AOP源码解析》、《JDBC详细全解》 简介 基于SpringBoot的Mybatis源码解析&#xff1a; 1.如何对mapper实例化bean 在加载BeanDefinition时&a…...

分布式文件管理系统(MinIO)

1.去中心化&#xff0c;每个点是对等的关系&#xff0c;通过Ngix对负载做均衡工作。 好处&#xff1a; 能够避免单点故障&#xff0c;将多块硬盘组成一个对象存储服务。 2. 使用纠删编码技术来保护数据&#xff0c;是一种回复丢失和损坏的数据的数学算法&#xff0c;他将数据分…...

Springcloud-配置中心config

一、添加依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId&…...

[项目篇] 音乐播放器开发报告

文章目录1. 项目描述:2. 项目上线展现&#xff1a;3. 项目具体实现&#xff1a;1. 登录2. 注册3.退出系统4.添加音乐4.1前后端交互约定4.2上传文件业务逻辑&#xff1a;4.3创建model包中的music类4.4在MusicMapper接口中&#xff0c;声明insertMusic抽象方法4.5在mybatis包中添…...

Spring Cloud Alibaba--gateway微服务详解之网关(二)

1、网关介绍 上篇对微服务中的nacos注册中心进行集成讲解。nacos主要作用是管理多服务之间复杂关系的组件。微服务是非常庞大且问题突出的架构&#xff0c;HTTP协议具有跨源资源共享 (CORS) Cross- Origin Resource Sharing机制&#xff0c;而处于安全考虑往往前端架构都会对跨…...

Zynq非VDMA方案实现视频3帧缓存输出,无需SDK配置,提供工程源码和技术支持

目录1、前言2、VDMA的不便之处3、FDMA取代VDMA实现视频缓存输出4、Vivado工程详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 对于Zynq和Microblaze的用户而言&#xff0c;要想实现图像缓存输出&#xff0c;多半要使用Xilinx推荐的VDMA方案&#xff0c;该…...

血液透析过滤芯气密性检测装置中的高精度多段压力控制解决方案

摘要&#xff1a;针对目前血液过滤芯气密性检测过程中存在的自动化水平较低、多个检测压力之间需人工切换和压力控制精度较差的问题&#xff0c;为满足客户对高精度和自动化气密性检测的要求&#xff0c;本文提出了相应的解决方案。解决方案的主要特点是全过程的可编程压力控制…...

PDF加密如何批量解除?快来了解下这个方法

在现代办公环境中&#xff0c;PDF文档的使用非常普遍。然而&#xff0c;由于一些安全需求&#xff0c;有时候PDF文档会被加密&#xff0c;使得只有授权人员可以查看或修改它。但是&#xff0c;如果您需要对许多加密PDF文档进行操作&#xff0c;逐个解密这些文档可能非常费时费力…...

C++——哈希4|布隆过滤器

目录 布隆过滤器 完整代码 布隆过滤器应用 布隆过滤器的查找 布隆过滤器删除 布隆过滤器优点 布隆过滤器缺陷 布隆过滤器海量数据处理 布隆过滤器 位图只能映射整形&#xff0c;而对于字符串却无能为力。 把字符串用哈希算法转成整形&#xff0c;映射一个位置进行标…...

python冒号的用法总结

一维数组 1. 单个冒号的情况 1.1 写完整的情况下 单个冒号的情况下&#xff0c;对数组的遍历操作是从前向后操作。如&#xff1a;arr[a:b] &#xff0c;冒号前的a含义是从a开始遍历&#xff0c;冒号后的b含义是到b截止&#xff08;不包括b&#xff09;。 arr [1, 2, 3, 4,…...

面试题整理

面试题整理 一、Java基础 1、Java 语言有哪些特点 简单易学&#xff1b; 面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b; 平台无关性&#xff08; Java 虚拟机实现平台无关性&#xff09;&#xff1b; 支持多线程&#xff08; C 语言…...

C语言深度解剖-关键字(7)

目录 switch case 语句 理解&#xff1a; 补充&#xff1a; 深入理解&#xff1a; default 语句&#xff1a; case语句&#xff1a; 总结&#xff1a; do、while、for 关键字 while for do while 各种死循环方法&#xff1a; while for do while getchar 写在…...

利用JavaScript编写Python内置函数查询工具

最近我开始学习Python编程语言&#xff0c;我发现Python拥有非常丰富的内置函数&#xff0c;可以用来实现各种不同的功能。但是每当我需要查找一个内置函数时&#xff0c;我总是需要联网使用搜索引擎进行查询。这种方式不仅费时费力&#xff0c;而且需要联网&#xff0c;很不方…...

【MySQL进阶】SQL优化

&#x1f60a;&#x1f60a;作者简介&#x1f60a;&#x1f60a; &#xff1a; 大家好&#xff0c;我是南瓜籽&#xff0c;一个在校大二学生&#xff0c;我将会持续分享Java相关知识。 &#x1f389;&#x1f389;个人主页&#x1f389;&#x1f389; &#xff1a; 南瓜籽的主页…...

最新版海豚调度dolphinscheduler-3.1.3配置windows本地开发环境

0 说明 本文基于最新版海豚调度dolphinscheduler-3.1.3配置windows本地开发环境&#xff0c;并在windows本地进行调试和开发 1 准备 1.1 安装mysql 可以指定为windows本地mysql&#xff0c;也可以指定为其他环境mysql&#xff0c;若指定为其他环境mysql则可跳过此步。 我这…...

csv文件完整操作总结

csv文件完整操作总结 1.概述 csv 模块主要用于处理从电子数据表格Excel或数据库中导入到文本文件的数据&#xff0c;通常简称为 comma-separated value &#xff08;CSV&#xff09;格式因为逗号用于分离每条记录的各个字段。 2.读写操作 2.1.测试数据 创建一个test.csv文…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...