【包装类&简单认识泛型】

目录

1,包装类

[1.1 基本数据类型和对应的包装类](#1.1 基本数据类型和对应的包装类)

[1.2 装箱和拆箱](#1.2 装箱和拆箱)

2,什么是泛型

3,引出泛型

[3.1 语法](#3.1 语法)

4,泛型如何编译的

[4.1 擦除机制](#4.1 擦除机制)

[4.2 为什么不能实例化泛型类型数组](#4.2 为什么不能实例化泛型类型数组)

5,泛型的上界

[5.1 语法](#5.1 语法)

[5.2 复杂示例](#5.2 复杂示例)

6,泛型方法


1,包装类

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

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

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

1.2 装箱和拆箱

装箱:把一个基本类型变成引用类型

这里划红线的原因是代表当前方法已经过时

不管是显示还是隐式,我们打开底层的汇编过程

发现自动装箱在底层也是调用的valueof,总的来说,valueof在给我们进行装箱

拆箱:把一个引用类型变成基本类型

进入底层查看汇编代码

还可以将其变成double类型

【面试题】

下列代码输出什么,为什么?

这里涉及到点是装箱,上面讲到过装箱在底层是调用的valueof来完成的,进入到valueof的源码

valueof调用了这个方法,发现i在if这个条件范围里面,就去cache这个数组里面取值,相反如果i不在这个范围里面,那么就会实例化一个新的对象,即根据上面代码的运行结果发现100在if条件范围里面,200实例化了一个新的对象,对应地址不同,所以范围false

进入high的源码:

观察发现这个数组的范围是[-127,128],即i的值在这个范围里面,就在这个数组里面取值,反之实例化新的对象

2,什么是泛型

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

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

3,引出泛型

把类型参数化,意味着可以传指定的类型参数---》如何实现呢?

首先想到的是:Object

需求:实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值

也就是说getValue的返回值是Object,他是一个父类类型,所以得强制类型转换

但是这种写法显得代码很乱,里面即可以存放int,又能存放String,甚至还可以存放double,而且还要进行强转,貌似是一个通用的,其实并不通用。

期望的是存指定类型数据,把参数传给Myarray

所以,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象。让编译器去做检查。此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。

3.1 语法

在<>里面可写E/T/E,T <T>代表当前类,是一个泛型类

上面代码就可以改动:

1,在实例化对象的时候已经指定当前类型为整型,每次存储数据的时候,会检查你存入的数据是不是和你指定的类型一样,若不一样,就会报错。(编译的时候)

2,此时不需要进行强制类型转换 运行的时候没有泛型这样的概念

并不是<T>替换成<Integer>,只是拿着它去检查的,并不是替换

那我们是否可以直接实例化T?

是不可以的,Java当中的数组是一种类型,所以实例化数组的时候要知道实例化的是一个什么样的数组,从此代码来看,并不知道T是一个什么,所以上面的T并没有替换成Integer,只是拿着它去检查类型是否匹配!!!

这样写也是存在问题的,下面会讲到

代码解释:

  1. 类名后的代表占位符,表示当前类是一个泛型类

  2. 不能new泛型类型的数组

  3. 类型后加入指定当前类型

  4. 不需要进行强制类型转换

  5. 编译器会在存放元素的时 候帮助我们进行类型检查

注意:泛型只能接受类,所有的基本数据类型必须使用包装类!

4,泛型如何编译的

运行的时候代码在JVM当中,也就是说在JVM当中没有泛型的概念

4.1 擦除机制

那么,泛型到底是怎么编译的?这个问题,也是曾经的一个面试问题。泛型本质是一个非常难的语法,要理解好他还是需要一定的时间打磨。

通过命令:javap -c 查看字节码文件,所有的T都是Object。

在编译的过程当中,将所有的T替换为Object这种机制,我们称为:擦除机制。

Java的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。

4.2 为什么不能实例化泛型类型数组

在上面讲到以下代码这种写法是有问题的

在MyArray里面添加一个方法

对此方法进行访问

这里报错了,类型转换异常,不能把Object转换成String类型的,getArray的返回值通过通过类型擦除是Object类型数组,Object类型数组给到String数组是不能给的,强转都不行

那为什么强转都不行呢?

我们说Object类是所以类的父类,但是Object[ ]不是所以数组的父类,他是一种单独的类型,所以就不能说Object[ ]是String[ ]的父类,Object是String的父类

所以就只能通过Object数组来接收

所以,以后都用Object来写

5,泛型的上界

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

5.1 语法

例如:

只接受 Number 的子类型作为 T 的类型实参,或者是Number自己

5.2 复杂示例

比如:定义一个泛型类,找到数组当中的最大值

6,泛型方法

还可以不实例化对象,将方法改写成静态方法,使用类名去调用即可

相关推荐
天使day几秒前
Maven
java·maven
汇匠源3 分钟前
共享无人系统,从出行到生活全面覆盖
java·生活
好开心3331 分钟前
axios的使用
开发语言·前端·javascript·前端框架·html
又蓝1 小时前
使用 Python 操作 Excel 表格
开发语言·python·excel
小灰灰要减肥1 小时前
装饰者模式
java
张铁铁是个小胖子1 小时前
MyBatis学习
java·学习·mybatis
余~~185381628001 小时前
稳定的碰一碰发视频、碰一碰矩阵源码技术开发,支持OEM
开发语言·人工智能·python·音视频
Am心若依旧4092 小时前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
明月看潮生2 小时前
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
开发语言·青少年编程·单元测试·编程与数学·goweb
Yan.love2 小时前
开发场景中Java 集合的最佳选择
java·数据结构·链表