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

Java 包装类简单认识泛型

学习目标:

1,以 能阅读Java集合源码 为目标 学习泛型

2,了解包装类

3,了解泛型

一,包装类

在java中,由于基本类型不是继承于Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型

1,基本数据类型和对应的包装类

举个例子来说明两者的关系

比如说基本数据类型 byte  可以定义变量 a = 10, 而它的包装类  Byte 不仅可以定义变量 a = 10,在Byte里还有许多方法可以使用,因为他是一个类

除了 Integer Character, 其余基本类型的包装类都是首字母大写。

2,装箱和拆箱:

装箱/装包:  自动装箱 显示装箱

拆箱/拆包:  自动拆箱 显示拆箱

什么是装箱:

基本数据类型 变为 包装类类型 的过程 叫做装箱

什么是拆箱:

包装类类型 变为 基本数据类型 的过程 叫做拆箱

1) 装箱

这个叫做自动装箱(隐式装箱)

这个叫做显示装箱

注意:无论是隐式还是显示装箱,底层都调用了valueOf方法

2) 拆箱

这个叫做自动拆箱(隐式拆箱)

这个叫做显示拆箱

3)小测试

这里有一段代码,猜一下输出的值是什么

是不是和你想的不太一样,为什么会这样?

我们想一下,这个过程是 装箱 对吧,那我们查看 装箱的源码 就得看 valueOf 的源码

这是valueOf的源码,可以看到,当变量的值在一个 范围 里面的时候,他返回的值 是直接从数组里拿的,当不在这个范围里的时候,直接返回一个 新的值,把新的值和旧值比较,结果必然不一样

那么,这个范围是什么呢?

从源码中看到,最小值是-128 最大值是127

因此在[-128 ~ 127]内的 256个数字 在进行 == 比较的时候都会输出 true

刚才说了在数组里取值,那这个数组是什么?

返回的这个数组,它的下标逻辑是    

也就是说,当 i = -128 的时候,这个数组的下标是 -128 + ( - ( - 128 ) ) = 0 当 i=127 的时候,数组的下标是127+128 = 255 

这个数组我们称为 缓存数组

明白了吧,那我们就不能在超出这个范围的时候 用我们正常的算术逻辑 去比较值了吗?当然不是,可以使用equals方法

二,泛型

一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。----- 来源《Java编程思想》对泛型的介绍。

1,什么是泛型

泛型是在JDK1.5引入的新的语法.
通俗讲,泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。

2,泛型的引出

现在要实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值,如何用代码实现?
分析:
1. 我们以前学过的数组,只能存放指定类型的元素,例如:
int[] array = new int[10]; String[] strs = new String[10];
2. 所有类的父类,默认为Object类。数组是否可以创建为Object?这样数组里不就可以存放任何类型的数据了吗?

这样数组里就可以存放你想要的任何类型了

但是

现在代码太乱了,主方法里什么类型都要放.更多情况下,我们还是希望他只能够持有一种数据类型。而不是同时持有这么多类型。并且每次取数据,都要进行强转,很麻烦
所以,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象。让编译器去做检查。此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。

3,泛型的语法

class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分类型参数
}

代码1示例:

分析代码1:

类定义:

首先我们放置了一个<E>,这个其实可以看做一个占位符,目的就是告诉编译器这是一个泛型E 是类型参数,代表该类可以操作任意类型的对象(后续使用时指定具体类型,如 Integer )

成员变量:

public Object[] arr = new Object[10]; 声明了一个长度为 10 的 Object 数组 arr,用于存储数据。因为是 Object 类型数组,理论上可以存储任何类型的对象,但实际使用时会根据泛型参数做类型转换

方法setValue:

public void SetValue(int pos, E val) 方法用于向数组 arr 的指定位置 pos 存储值 val。参数 pos 是数组索引,val 是要存储的、类型为 E 的值直接将 val 赋值给 arr[pos]

方法getValue:

public E getValue(int pos) 方法用于从数组 arr 的指定位置 pos 获取值,并将其转换为泛型类型 E 后返回通过 (E)arr[pos] 做强制类型转换,把 Object 类型的数组元素转换为 E 类型

主方法main:

MyArray<Integer> myArray = new MyArray(); 创建 MyArray 类的对象 myArray指定泛型类型为 Integer,但这里使用了原始类型创建(没有完整指定泛型参数,编译器会有警告 ),更规范的写法是 new MyArray<Integer>() 。当然不写也不报错

myArray.SetValue(1, 10); 调用 SetValue 方法,向 myArray 数组的索引 1 的位置存储值 10(因为泛型类型是 Integer,所以实际存储的是 Integer 类型的对象 )

那我们想要安放别的数据类型的时候怎么办,看代码:

代码2示例:

4,泛型是如何进行编译的

在编译的过程当中,将所有的T替换为Object这种机制,我们称为:擦除机制。
Java的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息

也就是说泛型是编译时期的一种机制,在运行的时候 没有泛型的概念

编译完成后, E 会被擦除为 Object

擦除机制是一个非常晦涩的机制,我们来简单认识一下就好

由于这里我没有重写 toString方法,因此这里会输出test类地址

(shujujiegou是我的包名,不用管)

发现了吗,无论是Integer类型还是String类型,都被擦掉了.

通俗讲,此时<>里的内容不参与类型的组成,类型就是MyArray这就是 擦除机制

5,泛型的上界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束

观察这个代码,和之前的代码有什么不同

这两处就是不同的地方

此时规定传入的参数是Number或者Number的子类,但是String不是Number的子类,所以报错

此时就指定了传入参数E的一个界限 而不是想传什么就传什么

语法:

像之前那种没有上界的,可以认为E extends Object

这是什么意思?

即 E必须是实现了Comparable接口的

http://www.dtcms.com/a/326352.html

相关文章:

  • Mysql——单表最多数据量多少需要分表
  • Redis 01 数据结构
  • SSM+Dubbo+Zookeeper框架和springcloud框架,写业务的时候主要区别在哪?
  • 【listlist模拟】
  • 提升行车安全的关键技术:BSD(盲点监测)与DSM(驾驶员监测)是如何工作的?
  • AI(领域)应用落地技术决策指南:从双路径架构到系统性实施
  • Centos 用http ftp搭建本地yum源 保姆级教程
  • 芯片学习 8 :IP集成、cluster、lint
  • 基于MongoDB/HBase的知识共享平台的设计与实现
  • 【09】中兴通讯——中兴 软件工程师 一面,校招,面试问答记录
  • 3DMAX快速散布插件QuickScatter安装使用方法
  • wrap cpp variant as dll for c to use
  • Horse3D引擎研发笔记(四):在QtOpenGL下仿three.js,封装EBO绘制四边形
  • copyleft的遗传特性
  • Python自动化测试实战:reCAPTCHA V3绕过技术深度解析
  • HTTPS应用层协议-中间攻击人
  • Spring AI赋能图像识别:大数据模型驱动下的智能化变革
  • 爬虫的云服务器代理
  • Linux中DNS系统搭建与配置指南(配实验步骤与注释)
  • 车型销售数据爬虫代码详细解释
  • MySQL入门基础
  • 【排序算法】⑥快速排序:Hoare、挖坑法、前后指针法
  • UE 保存游戏
  • 牛客.空调遥控二分查找牛客.kotori和气球(数学问题)力扣.二叉树的最大路径和牛客.主持人调度(二)
  • 数集相等定义凸显解析几何几百年重大错误:将无穷多各异点集误为同一集
  • 免费好用的数字人API
  • 使用dockge 安装 photoprism
  • 最短路问题从入门到负权最短路
  • elasticsearch的高可用
  • 【van-field 会记录上次选择并以悬浮弹窗再次展示】