JAVA基础学习笔记-day12-泛型

JAVA基础学习笔记-day12-泛型

    • 1. 泛型概述
      • 1.1 泛型的引入
    • 2. 使用泛型举例
      • 2.1 集合中使用泛型
      • 2.2 相关使用说明
    • 3. 自定义泛型结构
      • 3.1 泛型的基础说明
      • 3.2 自定义泛型类或泛型接口
        • 3.2.1 说明
        • 3.2.2 注意
      • 3.3 自定义泛型方法
        • 3.3.1 说明
    • 4. 泛型在继承上的体现
    • 5. 通配符的使用
      • 5.1 通配符的理解
      • 5.2 通配符的读与写
      • 5.3 使用注意点
      • 5.4 有限制的通配符

博文主要是自己学习JAVA基础中的笔记,供自己以后复习使用,参考的主要教程是B站的
尚硅谷宋红康2023大数据教程
水之积也不厚,则其负大舟也无力。—庄子《庄子·逍遥游》

1. 泛型概述

1.1 泛型的引入

在Java中,我们在声明方法时,当在完成方法功能时如果有未知的数据需要参与,这些未知的数据需要在调用方法时才能确定,那么我们把这样的数据通过形参表示。在方法体中,用这个形参名来代表那个未知的数据,而调用者在调用时,对应的传入实参就可以了。
受以上启发,JDK1.5设计了泛型的概念。泛型即为“类型参数”,这个类型参数在声明它的类、接口或方法中,代表未知的某种通用类型。
举例1:

集合类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK5.0之前只能把元素类型设计为Object,JDK5.0时Java引入了“参数化类型(Parameterized type)”的概念,允许我们在创建集合时指定集合元素的类型。比如:List<String>,这表明该List只能保存字符串类型的对象。
使用集合存储数据时,除了元素的类型不确定,其他部分是确定的(例如关于这个元素如何保存,如何管理等)。

java.lang.Comparable接口和java.util.Comparator接口,是用于比较对象大小的接口。这两个接口只是限定了当一个对象大于另一个对象时返回正整数,小于返回负整数,等于返回0,但是并不确定是什么类型的对象比较大小。JDK5.0之前只能用Object类型表示,使用时既麻烦又不安全,因此 JDK5.0 给它们增加了泛型。
在这里插入图片描述
其中<T>就是类型参数,即泛型。

所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值或参数的类型。这个类型参数将在使用时(例如,继承或实现这个接口、创建对象或调用方法时)确定(即传入实际的类型参数,也称为类型实参)。

2. 使用泛型举例

自从JDK5.0引入泛型的概念之后,对之前核心类库中的API做了很大的修改,例如:JDK5.0改写了集合框架中的全部接口和类、java.lang.Comparable接口、java.util.Comparator接口、Class类等。为这些接口、类增加了泛型支持,从而可以在声明变量、创建对象时传入类型实参。

2.1 集合中使用泛型

集合中没有使用泛型时:
在这里插入图片描述
集合中使用泛型时:
在这里插入图片描述

Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。即,把不安全的因素在编译期间就排除了,而不是运行期;既然通过了编译,那么类型一定是符合要求的,就避免了类型转换。
同时,代码更加简洁、健壮。
把一个集合中的内容限制为一个特定的数据类型,这就是generic背后的核心思想。

2.2 相关使用说明

  • 在创建集合对象的时候,可以指明泛型的类型。
    具体格式为:List list = new ArrayList();
  • JDK7.0时,有新特性,可以简写为:
    List list = new ArrayList<>(); //类型推断
  • 泛型,也称为泛型参数,即参数的类型,只能使用引用数据类型进行赋值。(不能使用基本数据类型,可以使用包装类替换)
  • 集合声明时,声明泛型参数。在使用集合时,可以具体指明泛型的类型。一旦指明,类或接口内部,凡是使用泛型参数的位置,都指定为具体的参数类型。如果没有指明的话,看做是Object类型。

3. 自定义泛型结构

3.1 泛型的基础说明

1、<类型>这种语法形式就叫泛型。

  • <类型>的形式我们称为类型参数,这里的"类型"习惯上使用T表示,是Type的缩写。即:。

  • :代表未知的数据类型,我们可以指定为,, 等。

    • 类比方法的参数的概念,我们把,称为类型形参,将 称为类型实参,有助于我们理解泛型
  • 这里的T,可以替换成K,V等任意字母。

2、在哪里可以声明类型变量<T>

  • 声明类或接口时,在类名或接口名后面声明泛型类型,我们把这样的类或接口称为泛型类泛型接口
【修饰符】 class 类名<类型变量列表>extends 父类】 【implements 接口们】{
    
}
【修饰符】 interface 接口名<类型变量列表>implements 接口们】{
    
}

//例如:
public class ArrayList<E>    
public interface Map<K,V>{
    ....
}    
  • 声明方法时,在【修饰符】与返回值类型之间声明类型变量,我们把声明了类型变量的方法,称为泛型方法。
[修饰符] <类型变量列表> 返回值类型 方法名([形参列表])[throws 异常列表]{
    //...
}

//例如:java.util.Arrays类中的
public static <T> List<T> asList(T... a){
    ....
}

3.2 自定义泛型类或泛型接口

当我们在类或接口中定义某个成员时,该成员的相关类型是不确定的,而这个类型需要在使用这个类或接口时才可以确定,那么我们可以使用泛型类、泛型接口。

3.2.1 说明

① 我们在声明完自定义泛型类以后,可以在类的内部(比如:属性、方法、构造器中)使用类的泛型。

② 我们在创建自定义泛型类的对象时,可以指明泛型参数类型。一旦指明,内部凡是使用类的泛型参数的位置,都具体化为指定的类的泛型类型。

③ 如果在创建自定义泛型类的对象时,没有指明泛型参数类型,那么泛型将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。

  • 经验:泛型要使用一路都用。要不用,一路都不要用。

④ 泛型的指定中必须使用引用数据类型。不能使用基本数据类型,此时只能使用包装类替换。

⑤ 除创建泛型类对象外,子类继承泛型类时、实现类实现泛型接口时,也可以确定泛型结构中的泛型参数。

如果我们在给泛型类提供子类时,子类也不确定泛型的类型,则可以继续使用泛型参数。

我们还可以在现有的父类的泛型参数的基础上,新增泛型参数。

3.2.2 注意

① 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1,E2,E3>

② JDK7.0 开始,泛型的简化操作:ArrayList flist = new ArrayList<>();

③ 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。

④ 不能使用new E[]。但是可以:E[] elements = (E[])new Object[capacity];

​ 参考:ArrayList源码中声明:Object[] elementData,而非泛型参数类型数组。

⑤ 在类/接口上声明的泛型,在本类或本接口中即代表某种类型,但不可以在静态方法中使用类的泛型。

⑥ 异常类不能是带泛型的。

3.3 自定义泛型方法

如果我们定义类、接口时没有使用<泛型参数>,但是某个方法形参类型不确定时,这个方法可以单独定义<泛型参数>。

3.3.1 说明
  • 泛型方法的格式:
[访问权限]  <泛型>  返回值类型  方法名([泛型标识 参数名称])  [抛出的异常]{
    
}
  • 方法,也可以被泛型化,与其所在的类是否是泛型类没有关系。
  • 泛型方法中的泛型参数在方法被调用时确定。
  • 泛型方法可以根据需要,声明为static的。

4. 泛型在继承上的体现

如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G并不是G的子类型!

比如:String是Object的子类,但是List并不是List的子类。
在这里插入图片描述

5. 通配符的使用

当我们声明一个变量/形参时,这个变量/形参的类型是一个泛型类或泛型接口,例如:Comparator类型,但是我们仍然无法确定这个泛型类或泛型接口的类型变量的具体类型,此时我们考虑使用类型通配符 ? 。

5.1 通配符的理解

使用类型通配符:?

比如:List<?>Map<?,?>

List<?>List<String>List<Object>等各种泛型List的父类。

5.2 通配符的读与写

写操作:

将任意元素加入到其中不是类型安全的:

Collection<?> c = new ArrayList<String>();

c.add(new Object()); // 编译时错误

因为我们不知道c的元素类型,我们不能向其中添加对象。add方法有类型参数E作为集合的元素类型。我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。

唯一可以插入的元素是null,因为它是所有引用类型的默认值。

读操作:

另一方面,读取List<?>的对象list中的元素时,永远是安全的,因为不管 list 的真实类型是什么,它包含的都是Object。

5.3 使用注意点

注意点1:编译错误:不能用在泛型方法声明上,返回值类型前面<>不能使用?

public static <?> void test(ArrayList<?> list){
}

注意点2:编译错误:不能用在泛型类的声明上

class GenericTypeClass<?>{
}

注意点3:编译错误:不能用在创建对象上,右边属于创建集合对象

ArrayList<?> list2 = new ArrayList<?>();

5.4 有限制的通配符

  • <?>

    • 允许所有泛型的引用调用
  • 通配符指定上限:<? extends 类/接口 >

    • 使用时指定的类型必须是继承某个类,或者实现某个接口,即<=
  • 通配符指定下限:<? super 类/接口 >

    • 使用时指定的类型必须是操作的类或接口,或者是操作的类的父类或接口的父接口,即>=
  • 说明:

    <? extends Number>     //(无穷小 , Number]
    //只允许泛型为Number及Number子类的引用调用
    
    <? super Number>      //[Number , 无穷大)
    //只允许泛型为Number及Number父类的引用调用
    
    <? extends Comparable>
    //只允许泛型为实现Comparable接口的实现类的引用调用
    
  • 举例1

    class Creature{}
    class Person extends Creature{}
    class Man extends Person{}
    
    class PersonTest {
        public static <T extends Person> void test(T t){
            System.out.println(t);
        }
    
        public static void main(String[] args) {
            test(new Person());
            test(new Man());
            //The method test(T) in the type PersonTest is not 
            //applicable for the arguments (Creature)
            test(new Creature());
        }
    }
    
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL面试题汇总

常规&#xff1a; 1、数据库三大范式 1NF : 表中字段的数据不可再拆分。(原子性)2NF : 在满足第一范式的情况下&#xff0c;遵循唯一性&#xff0c;消除部分依赖。即&#xff0c;表中任意一个主键或任意一组联合主键&#xff0c;可以确定除该主键外的所有的非主键值。(一个表…

(适趣AI)Vue笔试题

&#x1f4d1;前言 本文主要是【Vue】——&#xff08;适趣AI&#xff09;Vue笔试题的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 …

Android studio报错误提示 Some Kotlin libraries attached to this project 问题解决方案

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 Android新建项目后&#xff0c;报以下错误 错误提示内容为&#xff1a; 这个项目附带的一…

pygame学习(二)——绘制线条、圆、矩形等图案

导语 pygame是一个跨平台Python库(pygame news)&#xff0c;专门用来开发游戏。pygame主要为开发、设计2D电子游戏而生&#xff0c;提供图像模块&#xff08;image&#xff09;、声音模块&#xff08;mixer&#xff09;、输入/输出&#xff08;鼠标、键盘、显示屏&#xff09;模…

Spring Boot 与 Spring 框架的区别

一、前言 Spring Boot 和 Spring 框架是由 Spring 项目提供的两个关键的技术栈&#xff0c;它们在 Java 开发中扮演着不同的角色。在阐述其区别之前&#xff0c;我们先大致了解下这两个框架 二、Spring 框架 1、背景 Spring 框架是一个全栈的企业应用开发框架&#xff0c;起…

营销的尽头是矩阵!如何通过小魔推短视频矩阵快速破圈?

“ 营销的尽头是矩阵&#xff01; 相信很多做互联网的朋友都听过这么一句话 在抖音上我们看到过大批的博主&#xff0c;都是通过矩阵的方式火遍全网&#xff0c;就比如张琦、小杨哥等等&#xff0c;矩阵的方式适用于大多数的实体品牌&#xff0c;以及个人IP 等&#xff0c…

DevOps(3)

目录 11.描述root账户&#xff1f; 12.如何在发出命令时打开命令提示符&#xff1f; 14.Linux系统下交换分区的典型大小是多少&#xff1f; 15.什么是符号链接&#xff1f; 11.描述root账户&#xff1f; root账户就像一个系统管理员账户&#xff0c;允许你完全控制系统。 …

目标跟踪算法中的卡尔曼滤波学习

在使用多目标跟踪算法时&#xff0c;接触到卡尔曼滤波&#xff0c;一直没时间总结下&#xff0c;现在来填坑。 1. 背景知识 在理解卡尔曼滤波前&#xff0c;有几个概念值得考虑下&#xff1a;时序序列模型&#xff0c;滤波&#xff0c;线性动态系统 1. 时间序列模型 时间序…

AspectJ入门(二)— 应用

AspectJ便于调试、测试和性能调整工作。定义的行为范围从简单的跟踪到分析&#xff0c;再到应用程序内部一致性到测试。AspectJ可以干净地模块化这类功能&#xff0c;从而可以在需要时轻松地启用和禁用这些功能。 1 基础 本节将继续介绍AspectJ到一些基础功能&#xff0c;为后…

负载均衡案例:如何只用2GB内存统计20亿个整数中出现次数最多的整数

基于python实现。 如果是常规的小型文件&#xff0c;我们可以迅速地想到要建立字典。 以数字为key&#xff0c;以数字的出现次数为value&#xff0c;建立<int,int>类型的键值对存入字典&#xff0c;然后使用 max 函数结合字典的 items 方法来找到一个字典中 value 最大的…

2023 波卡年度报告选读:Polkadot SDK 与开发者社区

原文&#xff1a;https://dashboards.data.paritytech.io/reports/2023/index.html#section6 编译&#xff1a;OneBlock 编者注&#xff1a;Parity 数据团队发布的 2023 年 Polkadot 年度数据报告&#xff0c;对推动生态系统的关键数据进行了深入分析。报告全文较长&#xff…

一键减低PNG像素,轻松优化图片质量!

在数字时代&#xff0c;我们每天都要处理大量的图片文件&#xff0c;从网站设计、广告素材到社交媒体图片等。PNG作为一种常用的无损压缩格式&#xff0c;在保证图片质量的同时&#xff0c;也占用了较大的存储空间。为了优化存储空间和提高加载速度&#xff0c;我们需要对PNG图…

数据结构学习笔记——查找算法中的树形查找(B树、B+树)

目录 前言一、B树&#xff08;一&#xff09;B树的概念&#xff08;二&#xff09;B树的性质&#xff08;三&#xff09;B树的高度&#xff08;四&#xff09;B树的查找&#xff08;五&#xff09;B树的插入&#xff08;六&#xff09;B树的删除 二、B树&#xff08;一&#xf…

科技助力教育:数字化如何改变家校社协同育人?

近年来,随着社会的快速发展,教育的责任已不再仅局限于学校。家庭、学校和社会协同育人理念,正成为促进教育高质量发展的关键要素。 2023年初,教育部等十三部门联合印发《关于健全学校家庭社会协同育人机制的意见》,提出到“十四五”时期末,形成更加完善的由“学校积极主导、家…

Excel如何将单元格设为文本

文章目录 一、打开excel文件二、选中单元格三、右键设置单元格格式四、设置界面选择文本后点确定五、其他问题 在caa开发过程中遇到从CATUnicodeString转成CString时&#xff0c;通过SetItemText写入将ID号写入单元格&#xff0c;无法保存ID号中的数字0&#xff0c;故将单元格格…

统信UOS_麒麟KYLINOS修改图标显示名称

原文链接&#xff1a;统信UOS/麒麟KYLINOS修改图标显示名称 hello&#xff0c;大家好啊&#xff01;今天我要给大家介绍的是在统信UOS及麒麟KYLINOS操作系统上如何修改软件的名称。这种自定义可以帮助您更快地识别和访问常用的应用程序&#xff0c;也可以使您的桌面环境更加个性…

【MATLAB】CEEMD_LSTM神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 CEEMD-LSTM神经网络时序预测算法是一种结合了完全扩展经验模态分解&#xff08;CEEMD&#xff09;和长短期记忆神经网络&#xff08;LSTM&#xff09;的时间序列预测方法。 CEEMD是一种改…

基于MyCat2.0实现MySQL分库分表方案

目录 一、MyCat概述 二、MyCat作用 2.1 数据分片 2.1.1 垂直拆分 2.1.1.1 垂直分库 2.1.1.2 垂直分表 2.1.1.3 总结 2.1.2 水平拆分 2.1.2.1 水平分库 2.1.2.2 水平分表 2.1.2.3 总结 2.2 读写分离 2.3 多数据源整合 三、MyCat 与ShardingJDBC的区别 3.1 MyCat …

易基因:ChIP-seq等揭示Runx2通过转录调控Itgav表达激活肝星状细胞以促进肝纤维化|科研进展

这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 肌成纤维细胞&#xff08;myofibroblasts&#xff09;主要由肝脏中活化的肝星状细胞(hepatic stellate cells HSC)组成&#xff0c;在肝纤维化进展中发挥着核心作用。由于肌成纤维细胞主要负责细胞外基质蛋…

代码随想录刷题第三十六天| 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

代码随想录刷题第三十六天 无重叠区间 (LC 435) 题目思路&#xff1a; 代码实现&#xff1a; class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:intervals.sort(keylambda x: (x[0],x[1]))count 0right intervals[0][1]for i in ra…