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

目录

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,泛型方法

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

相关推荐
CryptoRzz6 分钟前
日本股票 API 对接实战指南(实时行情与 IPO 专题)
java·开发语言·python·区块链·maven
yugi9878388 分钟前
基于M序列的直扩信号扩频码生成方法及周期长码直扩信号的MATLAB实现方案
开发语言·matlab
程序员水自流9 分钟前
MySQL数据库自带系统数据库功能介绍
java·数据库·mysql·oracle
谷哥的小弟13 分钟前
Spring Framework源码解析——RequestContext
java·后端·spring·框架·源码
乾元14 分钟前
基于时序数据的异常预测——短期容量与拥塞的提前感知
运维·开发语言·网络·人工智能·python·自动化·运维开发
江上清风山间明月15 分钟前
使用python将markdown文件生成pdf文件
开发语言·python·pdf
j_xxx404_18 分钟前
C++算法入门:二分查找合集(二分查找|在排序数组中查找元素的第一个和最后一个位置)
开发语言·c++
天远Date Lab19 分钟前
Java微服务实战:聚合型“全能小微企业报告”接口的调用与数据清洗
java·大数据·python·微服务
ss27321 分钟前
阻塞队列:ArrayBlockingQueue如何用Lock与Condition实现高效并发控制
开发语言·python
lizz3124 分钟前
C++操作符重载深度解析
java·c++·算法