JAVA 包装类

个人网站地址:

http://xiaohe-blog.top

目录

包装类概述

包装类共性

装箱、拆箱

装箱

拆箱

自动装箱、自动拆箱

缓存池


包装类概述

什么是包装类?

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

基本数据类型

对应包装类

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了。

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值