Java—— 泛型详解

泛型概述

泛型是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查。
泛型的格式:<数据类型>
注意:泛型只能支持引用数据类型。

泛型的好处

没有泛型的时候,可以往集合中添加任意类型的数据,默认将集合中所有元素的数据类型都提升为Object类型,但是在获取数据的时候,数据都是Object类型,所以无法直接使用原来类型的特有方法,需要进行强转,如果不知道该强转成什么数据类型就没办法了。
此时推出了泛型,可以在添加数据的时候就把类型进行统一。
而且我们在获取数据的时候,也省的强转了,非常的方便。 

泛型的细节

1.泛型中不能写基本数据类型
2.指定泛型的具体类型的集合,添加数据时,可以添加该类类型或者其子类类型的数据
3.如果不写泛型,类型默认是Object 

泛型的分类

在类后面定义泛型为泛型类
在方法上面定义泛型为泛型方法
在接口后面定义泛型为泛型接口 

泛型类

使用场景

当一个类中,某个变量的数据类型不确定时,就可以定义带有泛型的类

格式

修饰符 class 类名 <类型> {

        ...

}

举例

public class MyArrayList <E> {

        ...
}

此处E可以理解为变量,但是不是用来记录数据的,而是记录数据的类型,常用T、E、K、V字母表示,创建该类对象时,E就确定类型

如果该类要使用多种类型的数据,可在<>中写多种变量通过逗号分隔,例如<E,T,K>

代码演示 

要求:定义一个类实现ArrayList中的部分方法 

import java.util.Arrays;//定义一个类实现ArrayList中的部分方法
public class MyArrayList<E>{//成员变量private Object[] obj = new Object[10];private int size;public MyArrayList() {}//添加元素方法public boolean add(E e){obj[size] = e;size++;return true;}//get方法public E get(int i){return (E)obj[i];}@Overridepublic String toString() {return obj.toString();}
}

测试类

public class Test {public static void main(String[] args) {MyArrayList<String> mal1 = new MyArrayList<>();mal1.add("aaa");mal1.add("bbb");System.out.println(mal1.get(1));//bbbMyArrayList<Integer> mal2 = new MyArrayList<>();mal2.add(1);mal2.add(2);System.out.println(mal2.get(1));//2}
}

 

泛型方法

使用场景

当一个方法,某个变量的数据类型不确定时,就可以定义带有泛型的方法

格式

修饰符 <类型> 返回值类型 方法名(类型 变量名){

        ...

}

举例

public <E> void show(E e){

        ...

}

调用该方法时E就确定类型

代码演示

定义一个工具类:ListUtil,类中定义一个静态方法addAll,用来添加多个集合的元素。

import java.util.ArrayList;
//定义一个工具类:ListUtil
//类中定义一个静态方法addAll,用来添加多个集合的元素。
public class ListUtil {private ListUtil() {}public static <E> void addAll1(ArrayList<E> list, E e1, E e2) {list.add(e1);list.add(e2);}//参数个数不确定时使用E...epublic static <E> void addAll2(ArrayList<E> list, E... e) {for (E element : e) {list.add(element);}}}

 测试类

import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<String> list1 = new ArrayList<>();ListUtil.addAll1(list1, "aaa", "bbb");System.out.println(list1);//[aaa, bbb]ArrayList<Integer> list2 = new ArrayList<>();ListUtil.addAll2(list2, 1, 2, 3, 4);System.out.println(list2);//[1, 2, 3, 4]}
}

细节

泛型类和泛型方法泛型方法都能解决方法中形参类型不确定的问题

区别:
使用类名后面定义的泛型:所有方法都能用
在方法申明上定义自己的泛型:只有本方法能用

泛型接口

使用场景

定义在接口名后面,表示接口实现类的类型

如何使用一个带泛型的接口

方式1:

实现类给出具体类型

方式2:

实现类延续泛型,创建对象时再确定

 

泛型的通配符

泛型不具备继承性,但是数据具备继承性。

指定泛型的具体类型的集合,添加数据时,可以添加该类类型或者其子类类型的数据

但是调用方法时,形参的泛型里面写的是什么类型,那么只能传递什么类型的数据

此时我们就可以使用泛型的通配符:
?也表示不确定的类型
? extends E:表示可以传递E或者E所有的子类类型
? super E:表示可以传递E或者E所有的父类类型 

练习

 

测试类中定义一个方法用于饲养动物
public static void keepPet(ArrayList<???> list){
        //遍历集合,调用动物的eat方法
}
要求1:该方法能养所有品种的猫,但是不能养狗
要求2:该方法能养所有品种的狗,但是不能养猫
要求3:该方法能养所有的动物,但是不能传递其他类型

import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<PersianCat> list1 = new ArrayList<>();ArrayList<LiHuaCat> list2 = new ArrayList<>();ArrayList<TeddyDog> list3 = new ArrayList<>();ArrayList<HuskyDog> list4 = new ArrayList<>();keepPet(list1);keepPet(list2);keepPet(list3);keepPet(list4);}//测试类中定义一个方法用于饲养动物//要求1:该方法能养所有品种的猫,但是不能养狗//public static void keepPet(ArrayList<? extends Cat> list) {}//要求2:该方法能养所有品种的狗,但是不能养猫//public static void keepPet(ArrayList<? extends Dog> list) {}//要求3:该方法能养所有的动物,但是不能传递其他类型public static void keepPet(ArrayList<? extends Animal> list) {}
}    abstract class Animal {public abstract void eat();}abstract class Cat extends Animal {}abstract class Dog extends Animal {}class PersianCat extends Cat {@Overridepublic void eat() {System.out.println("波斯猫吃东西");}}class LiHuaCat extends Cat {@Overridepublic void eat() {System.out.println("狸花猫吃东西");}}class TeddyDog extends Dog {@Overridepublic void eat() {System.out.println("泰迪狗吃东西");}}class HuskyDog extends Dog {@Overridepublic void eat() {System.out.println("哈士奇吃东西");}}

 

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

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

相关文章

通俗的桥接模式

桥接模式&#xff08;Bridge Pattern&#xff09; 就像一座桥&#xff0c;把两个原本独立变化的东西连接起来&#xff0c;让它们可以各自自由变化&#xff0c;互不干扰。简单来说&#xff0c;就是 “把抽象和实现分开&#xff0c;用组合代替继承”。 一句话理解桥接模式 假设你…

【现代深度学习技术】注意力机制04:Bahdanau注意力

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

爬虫学习————开始

&#x1f33f;自动化的思想 任何领域的发展原因————“不断追求生产方式的改革&#xff0c;即使得付出与耗费精力越来愈少&#xff0c;而收获最大化”。由此&#xff0c;创造出方法和设备来提升效率。 如新闻的5W原则直接让思考过程规范化、流程化。或者前端框架/后端轮子的…

每天五分钟机器学习:KTT条件

本文重点 在前面的课程中,我们学习了拉格朗日乘数法求解等式约束下函数极值,如果约束不是等式而是不等式呢?此时就需要KTT条件出手了,KTT条件是拉格朗日乘数法的推广。KTT条件不仅统一了等式约束与不等式约束的优化问题求解范式,KTT条件给出了这类问题取得极值的一阶必要…

leetcode0829. 连续整数求和-hard

1 题目&#xff1a; 连续整数求和 官方标定难度&#xff1a;难 给定一个正整数 n&#xff0c;返回 连续正整数满足所有数字之和为 n 的组数 。 示例 1: 输入: n 5 输出: 2 解释: 5 2 3&#xff0c;共有两组连续整数([5],[2,3])求和后为 5。 示例 2: 输入: n 9 输出: …

window 显示驱动开发-线性伸缩空间段

线性伸缩空间段类似于线性内存空间段。 但是&#xff0c;伸缩空间段只是地址空间&#xff0c;不能容纳位。 若要保存位&#xff0c;必须分配系统内存页&#xff0c;并且必须重定向地址空间范围以引用这些页面。 内核模式显示微型端口驱动程序&#xff08;KMD&#xff09;必须实…

Cadence 高速系统设计流程及工具使用三

5.8 约束规则的应用 5.8.1 层次化约束关系 在应用约束规则之前&#xff0c;我们首先要了解这些约束规则是如何作用在 Cadence 设计对象上的。Cadence 中对设计对象的划分和概念&#xff0c;如表 5-11 所示。 在 Cadence 系统中&#xff0c;把设计对象按层次进行了划分&#…

ScaleTransition 是 Flutter 中的一个动画组件,用于实现缩放动画效果。

ScaleTransition 是 Flutter 中的一个动画组件&#xff0c;用于实现缩放动画效果。它允许你对子组件进行动态的缩放变换&#xff0c;从而实现平滑的动画效果。ScaleTransition 通常与 AnimationController 和 Tween 一起使用&#xff0c;以控制动画的开始、结束和过渡效果。 基…

深入解析:如何基于开源p-net快速开发Profinet从站服务

一、Profinet协议与软协议栈技术解析 1.1 工业通信的"高速公路" Profinet作为工业以太网协议三巨头之一,采用IEEE 802.3标准实现实时通信,具有: 实时分级:支持RT(实时)和IRT(等时实时)通信模式拓扑灵活:支持星型、树型、环型等多种网络结构对象模型:基于…

m个n维向量组中m,n的含义与空间的关系

向量的维度与空间的关系&#xff1a; 一个向量的维度由其分量个数决定&#xff0c;例如 ( n ) 个分量的向量属于 Rn空间 。 向量组张成空间的维度&#xff1a; 当向量组有 ( m ) 个线性无关的 ( n ) 维向量时&#xff1a; 若 ( m < n )&#xff1a; 这些向量张成的是 Rn中的…

excel大表导入数据库

前文介绍了数据量较小的excel表导入数据库的方法&#xff0c;在数据量较大的情况下就不太适合了&#xff0c;一个是因为mysql命令的执行串长度有限制&#xff0c;二是node-xlsx这个模块加载excel文件是整个文件全部加载到内存&#xff0c;在excel文件较大和可用内存受限的场景就…

Python 爬虫基础入门教程(超详细)

一、什么是爬虫&#xff1f; 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;又称网页蜘蛛&#xff0c;是一种自动抓取互联网信息的程序。爬虫会模拟人的浏览行为&#xff0c;向网站发送请求&#xff0c;然后获取网页内容并提取有用的数据。 二、Python爬虫的基本原…

Spring Security 深度解析:打造坚不可摧的用户认证与授权系统

Spring Security 深度解析&#xff1a;打造坚不可摧的用户认证与授权系统 一、引言 在当今数字化时代&#xff0c;构建安全可靠的用户认证与授权系统是软件开发中的关键任务。Spring Security 作为一款功能强大的 Java 安全框架&#xff0c;为开发者提供了全面的解决方案。本…

【物联网】基于树莓派的物联网开发【1】——初识树莓派

使用背景 物联网开发从0到1研究&#xff0c;以树莓派为基础 场景介绍 系统学习Linux、Python、WEB全栈、各种传感器和硬件 接下来程序猫将带领大家进军物联网世界&#xff0c;从0开始入门研究树莓派。 认识树莓派 正面图示&#xff1a; 1&#xff1a;树莓派简介 树莓派…

第21节:深度学习基础-激活函数比较(ReLU, Sigmoid, Tanh)

1. 引言 在深度学习领域,激活函数是神经网络中至关重要的组成部分 它决定了神经元是否应该被激活以及如何将输入信号转换为输出信号 激活函数为神经网络引入了非线性因素,使其能够学习并执行复杂的任务 没有激活函数,无论神经网络有多少层,都只能表示线性变换,极大地限…

Fiori学习专题三十:Routing and Navigation

实际上我们的页面是会有多个的&#xff0c;并且可以在多个页面之间跳转&#xff0c;这节课就学习如何在不同页面之间实现跳转。 1.修改配置文件manifest.json&#xff0c;加入routing&#xff0c;包含三个部分&#xff0c;config,routes,targets; config &#xff1a; routerC…

【HarmonyOS NEXT+AI】问答05:ArkTS和仓颉编程语言怎么选?

在“HarmonyOS NEXTAI大模型打造智能助手APP(仓颉版)”课程里面&#xff0c;有学员提到了这样一个问题&#xff1a; 鸿蒙的主推开发语言不是ArkTS吗&#xff0c;本课程为什么使用的是仓颉编程语言&#xff1f; 这里就这位同学的问题&#xff0c;统一做下回复&#xff0c;以方便…

Booth Encoding vs. Non-Booth Multipliers —— 穿透 DC 架构看乘法器的底层博弈

目录 &#x1f9ed; 前言 &#x1f331; 1. Non-Booth 乘法器的实现原理&#xff08;也叫常规乘法器&#xff09; &#x1f527; 构建方式 ✍️ 例子&#xff1a;4x4 Non-Booth 乘法器示意 &#x1f9f1; 硬件结构 ✅ 特点总结 ⚡ 2. Booth Encoding&#xff08;布斯编码…

GET请求如何传复杂数组参数

背景 有个历史项目&#xff0c;是GET请求&#xff0c;但是很多请求还是复杂参数&#xff0c;比如&#xff1a;参数是数组&#xff0c;且数组中每一个元素都是复杂的对象&#xff0c;这个时候怎么传参数呢&#xff1f; 看之前请求直接是拼接在url后面 类似&items%5B0%5D.…

iOS App 安全性探索:源码保护、混淆方案与逆向防护日常

iOS App 安全性探索&#xff1a;源码保护、混淆方案与逆向防护日常 在 iOS 开发者的日常工作中&#xff0c;我们总是关注功能的完整性、性能的优化和UI的细节&#xff0c;但常常忽视了另一个越来越重要的问题&#xff1a;发布后的应用安全。 尤其是对于中小团队或独立开发者&…