面试突击:Java 中的泛型
本文已收录于:https://github.com/danmuking/all-in-one(持续更新)
前言
哈喽,大家好,我是 DanMu。今天想和大家聊聊 Java 中的泛型。
什么是泛型?
Java 泛型(Generics) 是 JDK 5 中引入的一个新特性。它允许我们通过预先定义模板,为多种不同的数据类型执行相同的逻辑,实现更好的代码复用。
Java 编译器实现了对泛型参数进行检测,并且运行我们通过泛型参数来指定传入的对象类型,比如ArrayList<Integer> list = new ArrayList<Integer>()
就指定了这个 ArrayList 中只能存放 Integer 对象,如果传入其他类型的对象就会报错。
为什么需要泛型?
引入泛型的意义在于:
- 适用于多种数据类型执行相同的代码(代码复用)
如果没有泛型,即使是通用的逻辑,也需要针对每种类型单独进行一次重载,比如下面这个例子:
private static int add(int a, int b) {System.out.println(a + "+" + b + "=" + (a + b));return a + b;
}private static float add(float a, float b) {System.out.println(a + "+" + b + "=" + (a + b));return a + b;
}private static double add(double a, double b) {System.out.println(a + "+" + b + "=" + (a + b));return a + b;
}
这不是耽误我赚个小目标的进度嘛。为了帮助我们更快的赚到小目标,Java 贴心的为我们设计了泛型方法,现在我们可以用泛型的方式来重写一下上面的代码:
private static <T extends Number> add(T a, T b) {System.out.println(a + "+" + b + "=" + (a.doubleValue() + b.doubleValue()));return a.doubleValue() + b.doubleValue();
}
在这端代码中,使用了一个泛型<T extends Number>
来代替了上面出现的所有数字类型,在使用时,我们只需要指定 T 的类型,编译器就会自动的帮助我们将方法中的 T 转换为对应的类型,因此只需要一个函数就能实现所有数字类型的加法。
- 泛型中的类型可以在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
比如下面这个例子:
List list = new ArrayList();
list.add("联系时长");
list.add(2.5);
list.add("的练习生");
在上述 list 中,list 中的所有元素都是Object类型,因此,我们在取出集合元素时需要手动进行强制类型转化,将Object 转换到具体的目标类型,不仅麻烦而且很容易出现java.lang.ClassCastException
异常。
通过引入泛型,它能够为我们进行类型的约束,提供编译前的检查:
List<String> list = new ArrayList<String>(); // list中只能放String, 不能放其它类型的元素
如何使用泛型?
泛型主要的使用方式有三种:泛型类、泛型接口、泛型方法。
泛型类:
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{private T key;public Generic(T key) {this.key = key;}public T getKey(){return key;}
}
如何实例化泛型类:
Generic<Integer> genericInteger = new Generic<Integer>(123456);
泛型接口:
public interface Generator<T> {public T method();
}
实现泛型接口,不指定类型:
class GeneratorImpl<T> implements Generator<T>{@Overridepublic T method() {return null;}
}
实现泛型接口,指定类型:
class GeneratorImpl<T> implements Generator<String>{@Overridepublic String method() {return "hello";}
}
泛型方法:
public static < E > void printArray( E[] inputArray )
{for ( E element : inputArray ){System.out.printf( "%s ", element );}System.out.println();
}
使用:
// 创建不同类型数组:Integer, Double 和 Character
Integer[] intArray = { 1, 2, 3 };
String[] stringArray = { "Hello", "World" };
printArray(intArray);
printArray(stringArray);
注意:
public static <E> void printArray(E[] inputArray )
一般被称为静态泛型方法;在 Java 中泛型只是一个占位符,必须在传递类型后才能使用。类在实例化时才能真正的传递类型参数,由于静态方法的加载先于类的实例化,也就是说类中的泛型还没有传递真正的类型参数,静态的方法的加载就已经完成了,所以静态泛型方法是没有办法使用类上声明的泛型的。只能使用自己声明的
泛型的上下限
有时候我们不希望某个泛型能够被所有类型使用,比如这个例子:
private static void printText(T a) {System.out.println(a.text);
}// 使用
add(1);
在方法中将会输出传入对象的 text 属性,但是如果当传入对象没有 text 属性或者 text 属性不可以直接访问,程序就会报错。OMG!这就很糟糕了,并且这段代码可以很容易的通过编译检查,只有在运行时错误才会被发现。为了减少这种情况的发生,我们需要一种机制,能够将泛型允许接受的对象类型限制在一定的范围内。
在 Java 中提供了 extends 和 super 两个关键字来限制泛型的范围:
extends 关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类
class Info<T extends Number>{ // 此处泛型只能是数字类型private T var ; // 定义泛型变量public void setVar(T var){this.var = var ;}public T getVar(){return this.var ;}public String toString(){ // 直接打印return this.var.toString() ;}
}
public class demo1{public static void main(String args[]){Info<Integer> i1 = new Info<Integer>() ; // 声明Integer的泛型对象Info<List> i1 = new Info<List>() ; // 报错}
}
super 关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类
public class demo2 {public static void main(String[] args) {List<? super Number> number = new ArrayList<Number>();number.add(314);String a = "test";// number.add(a); 报错getUperNumber(number);}// <?> 无限制通配符public static void getUperNumber(List<?> data) {System.out.println("data :" + data.get(0));}
}
如果需要进行多种条件的限制,可以用 & 将多个条件连接起来:
public class Client {//工资低于2500元的上斑族并且站立的乘客车票打8折public static <T extends Staff & Passenger> void discount(T t){if(t.getSalary()<2500 && t.isStanding()){System.out.println("恭喜你!您的车票打八折!");}}public static void main(String[] args) {discount(new Me());}
}
点关注,不迷路
好了,以上就是这篇文章的全部内容了,如果你能看到这里,非常感谢你的支持!
如果你觉得这篇文章写的还不错, 求点赞👍 求关注❤️ 求分享👥 对暖男我来说真的 非常有用!!!
白嫖不好,创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!
如果本篇博客有任何错误,请批评指教,不胜感激 !
最后推荐我的IM项目DiTing(https://github.com/danmuking/DiTing-Go),致力于成为一个初学者友好、易于上手的 IM 解决方案,希望能给你的学习、面试带来一点帮助,如果人才你喜欢,给个Star⭐叭!
参考资料
Java 基础 - 泛型机制详解
相关文章:
面试突击:Java 中的泛型
本文已收录于:https://github.com/danmuking/all-in-one(持续更新) 前言 哈喽,大家好,我是 DanMu。今天想和大家聊聊 Java 中的泛型。 什么是泛型? Java 泛型(Generics) 是 JDK 5…...
3_2、MFC常用控件用法:组合框、滚动条和图片控件
MFC控件用法 1、组合框1.1 简介1.2 创建CComboBox类的主要成员函数 1.3 实例 2、滚动条控件2.1 简介2.2 创建CScrollBar类的主要成员函数 2.3 实例 3、图片控件3.1 简介3.2 创建图片控件静态加载图片图片控件动态加载图片 1、组合框 1.1 简介 组合框其实就是把一个编辑框和一…...
如何使用gprof对程序进行性能分析
如何使用gprof对程序进行性能分析 目录 1 gprof概述 2 gprof原理简述 3 gprof使用 3.1 gprof使用简述 3.2 gprof使用示例 4 小结 1 gprof概述 gprof 是 一个 GNU 的程序性能分析工具,可以用于分析C\C程序的执行性能。gprof工具可以统计出各个函数的调用次数、执…...
四川汇聚荣科技有限公司靠谱吗?
在如今这个信息爆炸的时代,了解一家公司是否靠谱对于消费者和合作伙伴来说至关重要。四川汇聚荣科技有限公司作为一家位于中国西部地区的企业,自然也受到了人们的关注。那么,这家公司究竟如何呢?接下来,我们将从多个角度进行深入…...
可灵王炸更新,图生视频、视频续写,最长可达3分钟!Runway 不香了 ...
现在视频大模型有多卷? Runway 刚在6月17号 发布Gen3 ,坐上王座没几天; 可灵就在6月21日中午,重新夺回了王座!发布了图生视频功能,视频续写功能! 一张图概括: 二师兄和团队老师第一…...
oracle中使用临时表GLOBAL TEMPORARY TABLE
需要在存储过程中返回一个临时结果集,这个结果集又是多个语句通过循环查询出来的,这时候就想到了将结果插入到临时表中,然后返回临时表的数据的思路,于是有了以下操作: 1.创建临时表 -- Create table create global …...
Gradio入门—快速开始
目录 安装构建您的第一个演示分享您的演示核心 Gradio 课程聊天机器人gr.ChatInterface自定义演示gr.BlocksGradio Python 和 JavaScript 生态系统 Gradio 是一个开源 Python 软件包,可让您快速为机器学习模型、API 或任何任意 Python 函数构建演示或 Web 应用程序。…...
AOP应用之系统操作日志
本文演示下如何使用AOP,去实现系统操作日志功能。 实现步骤 引入AOP包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.6.6</version></de…...
海外云手机自动化管理,高效省力解决方案
不论是企业还是个人,对于海外社媒的营销都是需要自动化管理的,因为自动化管理不仅省时省力,而且还节约成本; 海外云手机的自动化管理意味着什么?那就是企业无需再投入大量的人力和时间去逐一操作和监控每一台设备。 通…...
后仿真中的 《specify/endspecify block》之(5)使用specify进行时序仿真
前面我们学习了specify...endspecify 具体是什么东西。今天,我们使用specify block 中定义的延时,来进行一次仿真。看看到底是背后如何运转的呢。 一 基本例子 一个用 specify 指定延迟的与门逻辑描述如下: module and_gate(output Z,input A, B);assign Z = A & …...
win10/11磁盘管理
win10/11磁盘管理 合并磁盘分区的前提是你的两个磁盘区域是相邻的,比如如下: 如果需要吧这个磁盘进行分解,你可以选择压缩一部分磁盘或者是直接删除卷 我这里的话,因为压缩出来的卷和C盘好像是不相邻的(我之前做过&…...
【昇思初学入门】第四天打卡
数据变换Transforms 心得体会 MindSpore提供了丰富的数据变换工具,针对图像数据可以使用如Rescale、Normalize和HWC2CHW等,且使用Compose类允许我们定义一个变换序列,并将它们作为一个整体应用到数据上。 composed transforms.Compose([v…...
禁用/屏蔽 Chrome 默认快捷键
Chrome 有一些内置的快捷键,但是它并没有像其他软件一样提供管理快捷键的界面。在某些时候,当我们因为个人需求希望禁用 Chrome 某些快捷键时,又无从下手。 好在有开发者开发了 Chrome 插件,可以禁用 Chrome 快捷键的插件&#x…...
移动端+PC端应用模式的智慧城管综合执法办案平台源码,案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析
城市管理综合执法管理平台实现执法办案、业务全流程在线办理,依托移动端PC端的“两端”应用模式,保障能够通过信息化手段进行日常的执法办案工作,强化执法监督功能。提供了案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析等功能&a…...
AI音乐大模型时代:版权归属与创意产业的新生长点
AI在创造还是毁掉音乐? 简介:最近一个月,轮番上线的音乐大模型,一举将素人生产音乐的门槛降到了最低,并掀起了音乐圈会不会被AI彻底颠覆的讨论。短暂的兴奋后,AI产品的版权归属于谁,创意产业要…...
C++函数作为参数
C++函数作为参数 在C++中,函数作为另一个函数的参数是非常常见的做法,特别是在处理回调函数和泛型编程时。我们展示了如何在C++中将函数作为参数传递给另一个函数,包括普通函数、std::function 和 std::bind、lambda表达式以及类成员函数。每种方法都有其独特的优势,可以根…...
考前刷题练手感(北航期末往年数据结构编程题)
本次因为是考前一天极速刷题,所以没有讲解,若有问题可私信。 目录 一、 查找同时空人员二、 老鼠回家-无回路三、函数调⽤关系四、东二食堂模拟五、栈帧 一、 查找同时空人员 【问题描述】 假设一共有6个手机基站,都具有记录手机连接基站状…...
Android记录9--实现转盘效果
自定义View /2013.10.16_TurnPlate_Demo/src/com/wwj/turnplate/TurnPlateView.java package com.wwj.turnplate; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; im…...
【Oracle APEX开发小技巧1】转换类型实现显示小数点前的 0 以 及常见类型转换
在 apex 交互式式网格中,有一数值类型为 NUMBER,保留小数点后两位的项,在 展示时小数点前的 0 不显示。 效果如下: 转换前: m.WEIGHT_COEFFICIENT 解决方案: 将 NUMBER(20,2…...
GRIT论文阅读笔记
一篇试图统一生成任务和编码任务的工作,就是把只能完成生成任务的GPT改成既能生成又能encode。思路其实很简单,就是在输入的时候添加instruction tokens来指引模型做representation还是generation,然后各自算损失。representation任务用的是d…...
1980python个性化电影推荐管理系统mysql数据库Django结构layUI布局elasticsearch存储计算机软件工程网页
一、源码特点 python Django个性化电影推荐管理系统是一套完善的web设计系统mysql数据库 利用elasticsearch存储浏览数据 ,对理解python编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 开发环境pycharm…...
基于IDEA的Maven(依赖介绍和引用)
如何通过一个坐标信息(依赖)去引用 ,某个"jar 包" 会在这篇博客进行学习。 目录 一、学习开始 (0)项目的结构组成和 "pom.xml" 文件内容。 (1)首先需要一个标签…...
pytest测试框架pytest-sugar插件生成进度条
Pytest提供了丰富的插件来扩展其功能,介绍下插件pytest-sugar,可以帮助我们在控制台中显示彩色的测试结果和进度条,提供失败的堆栈回溯信息。 为了使用 pytest-sugar,需要满足以下条件: Python 3.8 或更高版本pytest…...
若依框架集成微信支付
1. 添加微信支付相关依赖 <!-- 微信支付 --> <dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version> </dependency> <dependency><groupId>com.gi…...
IOS开发学习日记(十七)
简单的第三方登录和分享功能 第三方登录系统 URL Scheme:App间的跳转及通信 App间跳转场景 登陆系统: 跨平台,跨App 标记用户,个性化的推送 使用第三方登录(减少注册成本 / 无须维护敏感信息) 微信 / Q…...
【ARMv8/ARMv9 硬件加速系列 2 -- ARM NEON 加速运算介绍】
文章目录 ARM NEONNEON 向量寄存器NEON 寄存器使用方式NEON 寄存器的视图NEON 寄存器别名NEON 寄存器的用途ARM NEON 在ARMv8架构中,引入了一组新的寄存器,称为向量寄存器(Vector Registers),用于支持高效的向量和浮点计算。这些寄存器是SIMD(Single Instruction, Multi…...
LayoutSystem布局系统
简介: LayoutSystem,是UGUI中由CanvasUpdateSystem发起(m_LayoutRebuildQueue中大部分都是LayoutRebuilder)的关于布局排列的处理系统。 类图: 布局过程 核心代码讲解: LayoutRebuilder...
滚球游戏笔记
1、准备工作 (1) 创建地面:3D Object-Plane,命名为Ground (2) 创建小球:3D Object-sphere,命名为Player,PositionY 0.5。添加Rigidbody组件 (3) 创建文件夹:Create-Foder,分别命名为Material…...
Mysql8死锁排查
Mysql8死锁排查 Mysql8 查询死锁的表 -- 查询死锁表select * from performance_schema.data_locks;-- 查询死锁等待时间select * from performance_schema.data_lock_waits;Mysql8之前的版本 查询死锁的表 -- 查询死锁表SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;-- 查询…...
程序猿成长之路之数据挖掘篇——决策树分类算法(1)——信息熵和信息增益
决策树不仅在人工智能领域发挥着他的作用,而且在数据挖掘中也在分类领域中独占鳌头。了解决策树的思想是学习数据挖掘中的分类算法的关键,也是学习分类算法的基础。 什么是决策树 用术语来说,决策树(Decision Tree)是…...
IT做网站工资怎么样/自动点击器永久免费版
我们在使用inline-block是时候,可能会出现一个问题,就是元素之间出现间隙。 我们看看代码: <style> li {display:inline-block;width:20px;height:20px;background-color:red; } ul {width:90px;background-color:blue; } </style…...
wordpress所有数据迁移/推广计划怎么做推广是什么
单一职责原则是面向对象原则五大原则中最简单,也是最重要的一个原则, 他的字面定义如下: 单一职责原则(Single Responsibility Principle, SRP): 一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言&a…...
哪些网站可以做文字链广告/百度知识营销
使用织梦过程中,难免会遇到一些难以预料的错误,当然,这些错误有dedecms自身的漏洞,也有因为我们自己二次开发过程中留下的漏洞,今天,我们就来谈一谈织梦后台更改栏目时出现“保存当前栏目更改时失败&#x…...
网站怎么做一盘优化排名/天猫店铺申请条件及费用
VC维含义的个人理解 有关于VC维可以在很多机器学习的理论中见到,它是一个重要的概念。在读《神经网络原理》的时候对一个实例不是很明白,通过这段时间观看斯坦福的机器学习公开课及相关补充材料,又参考了一些网络上的资料(主要是这…...
电子商务网站怎么做数据库/sem技术培训
译 原文:https://dev.to/chrissiemhrk/git-commit-message-5e21 提交信息是对提交之前添加和更改的文件所做的更改的简短描述。 良好的提交信息不仅对你所参与的项目上其它的团队成员很重要,对你自己而言也很重要,你需要跟踪所有提交&am…...
2015年做那个网站能致富/网站模板哪里好
ZAB(Zookeeper Atomic Broadcast) 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeeper 实现了一种主备模式…...