IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JAVA 包装类 -> 正文阅读

[Java知识库]JAVA 包装类

目录

包装类概述

包装类共性

装箱、拆箱

装箱

拆箱

自动装箱、自动拆箱

缓存池


包装类概述

什么是包装类?

基本数据类型的强化版,你可以把基本数据类型理解为 托尼 · 斯塔克,包装类理解为钢铁侠。

基本数据类型

对应包装类

byte

Byte

char

Character

short

Short

int

Integer

long

Long

float

Float

double

Double

boolean

Boolean

为什么要使用包装类?

众所周知,在JAVA里万事万物皆为对象,但是8种基本数据类型似乎鹤立鸡群,它们能完成的功能很少,所以JAVA类库提供了包装类。如果学到后面的集合你就会发现,集合都不支持基本数据类型。

又比如,你想知道int类型的最大值具体是多少,难道还要去用计算器算吗?直接使用Integer.MAX_VALUE 就可以获取你想要的。它还有更多功能,将十进制转换为二进制、八进制、十六进制、将n进制转换成十进制.....

包装类共性

1、所有包装类都没有无参构造函数

2、所有包装类的底层值都不可变

3、每一个包装类都有静态常量:MAX_VALUE 、MIN_VALUE (Boolean除外)

4、所有包装类都提供了装箱方法:valueOf()。拆箱方法:类型value()

共性1:包装类没有无参构造函数

共性2:包装类的底层值都不可变

共性3:每一个包装类都有静态常量:MAX_VALUE 、MIN_VALUE(Boolean除外)

共性4、所有包装类都提供了装箱方法:valueOf()。拆箱方法:类型value()

Integer I = new Integer(5); // 装箱
int i = I.intValue(); // 拆箱

Double D = new Double(5.2); // 装箱
double d = D.doubleValue(); // 拆箱

装箱、拆箱

什么是装箱、拆箱?

装箱 :将 int 转换为 Integer,也就是把int包装起来

拆箱 :将 Integer 转换为 int,也就是把Integer褪下包装

装箱

装箱 :将 int 转换为 Integer

方法一:使用构造函数

new Integer(int value);
new Integer(String s);

看,输出i,直接输出了93,也就是说包装类重写了toString()方法,能够直接输出它底层的值。

方法二:使用静态方法

Integer.valueOf(int value);
Integer.valueOf(String s);

拆箱

拆箱 :将 Integer 转换为 int,也就是把Integer褪下包装

使用方法 类型Value() (这个不是静态方法哦,要与装箱区分开)

Integer I = new Integer(10); // 装箱
int i = I.intValue(); // 拆箱

Character C = new Character('h'); // 拆箱
char c = C.charValue(); // 拆箱

Double D = new Double(5.2); // 装箱
double d = D.doubleValue(); // 拆箱

有人说parseInt()也可以理解为拆箱,parseInt()是将一个Integer对象或者字符串转换成int值。这个看你要怎么想了。

Integer I = new Integer(10);
int i = I.parseInt();

这里要重点讲一下valueOf() 这个方法,为更好理解自动装箱/拆箱铺垫。

经过刚才的学习,我们已经知道了valueOf是将一个int值装换成Integer值,那么他的原理是什么呢?

我们可以查看它的源码:

可以看到,如果没有触发一开始的if:

if (i >= IntegerCache.low && i <= IntegerCache.high)
    return IntegerCache.cache[i + (-IntegerCache.low)];

这个条件的话,valueOf()的底层其实还是调用了new Integer(i)来new一个对象。

那么这个奇奇怪怪的条件是什么呢?留一个悬念。下面会讲

自动装箱、自动拆箱

由于包装类实在是太常用太常用了,我们难道要一直new Integer对象或者打出Integer.valueOf()这样冗余的代码吗?

为了简化这个过程,让包装类更加容易上手,JAVA工程师在设计包装类时就已经做了优化。

Integer I = 5;
Double D = 1.0;
Boolean B = true;

是不是比刚才那些繁琐的代码轻松了很多?

那么如此轻松的代码是如何实现的呢?

其实他的本质还是调用了Integer.valueOf()我们可以使用反编译工具XJad查看

(如果你没有反编译工具或者不会使用它,可以借鉴:JAVA查看反编译代码)

Integer I = 5;

可以看到,自动装箱时,默认调用Integer.valueOf() 方法,不用我们辛辛苦苦去写了。

接下来看自动拆箱

Integer I = 5; // 自动装箱
int i = I; // 自动拆箱

我们依旧使用XJad查看

看,他其实也是调用了intValue()方法。

所以说,自动装箱、拆箱与手动装箱拆箱的差别只有:更加方便。

有了基础,可以看看这些练习题了:

// 手动装箱
1、Integer A = new Integer("23");
2、Integer B = Integer.valueOf("23");
3、Integer C = Integer.parseInt("23");
4、Double D = new Double();
5、Double E = Double.valueOf("23.4");
6、int i = (Integer.valueOf("23")).intValue();
7、double d = (Double.valueOf("23.4")).doubleValue();
// 自动装箱
8、Integer x = 3 + new Integer(5);
9、int x = new Integer(3) + new Integer(4);
10、Double x = 3;

有些题很简单,挑一些难的浅讲一下

3、Integer C = Integer.parseInt("23"); 将"23"转换为int值,再将int值自动装箱。

4、Double D = new Double(); 报错,包装类没有无参构造。

8、Integer x = 3 + new Integer(5); 构造一个Integer(5),再将它拆箱为(int)5,与3相加,得值(int)8 ,再将8自动装箱为Integer(8)。

9、int x = new Integer(3) + new Integer(4); 检测到符号:"+",将两侧的(Integer)3和(Integer)4自动拆箱为(int)3和(int)4,相加得值7。

10、(int)3装箱为Integer,发现要的是Double,所以报错。

使用XJad查看刚才第8题和第9题的分析:

缓存池

还记得刚刚遗留的问题吗?对,就是Integer.valueOf()下面的一大串条件IntegerCache巴拉巴拉的

在讲缓存池之前有一个问题:

Integer A = 100;
Integer B = 100;
Integer C = 200;
Integer D = 200;
A == B ?
C == D ?

A和B相等吗?C和D相等吗?跑一下。

奇怪的事情发生了,为什么A == B,而C != D呢?

这就是 缓存池。

由于包装类实在是太常用了,自动装箱仅仅简化了代码,但包装类底层的值是不可改变的,所以空间并没有少用,你每次使用同一个数都需要在堆区重复new空间。

所以JAVA工程师就推出了一个和String类节省空间类似的方法:缓存池,即IntegerCache。

可以看到IntegerCache是一个内部类,

成员变量有: low = -128high, 和一个Integer数组cache

在你使用它之前,他其实已经做了很多东西:

把 -128 ~ 127 之间的数先new出来放到Integer数组cache[]中,当你要使用 -128 ~ 127时,直接在这个数组中拿给你,不再new空间。即:你即使用了一万次1,他始终是cache[]里的那个1,这样就能有效防止空间浪费。当然,不止Integer有缓存池,其他包装类也有缓存池。

让我们梳理一下思路(举例Integer):

自动装箱默认调用Integer.valueOf(),如果这个数在 -128 ~ 127之间,那么直接在缓存池中取,如果不在这个区间,就得重新new了。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:11:09  更:2022-04-27 11:11:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:34:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码