持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
包装类的介绍
为啥出现
equals 方法和 “==” 进行比较操作时,数据类型一致才有比较的意义。
简单类型之间可以进行比较,引用类型之间可以比较,但是简单类型不能和应用类型进行比较
而包装类的出现正是简单类型到引用类型之间转换的桥梁
很多时候会碰上这样一种场景:
我接收到一个值 “123”,它是个字符串,但是呢,我需要这个值进行后续的计算,往往我们会这样写
String s = "123";
int i = s + 456;
int i = s + 456; 字符串对象 s 怎么能和数值进行计算呢,那怎么办呢?
有人会想到的是做显式转换,也就是将语句修改为 int i = (int)s + 456; ,往往在很多时候,我们就会这样去做。
- 那么为啥不能这样做显式转换呢?
因为简单类型和引用类型之间是不能直接进行转换操作的,我们需要包装类进行转换处理。
简单类型需要转换为字符串,最简单的方式就是在后面加上一个空的字符串,相信你一定写过,代码如下:
String s2 = i7 + "";
- 但是这种方式我们不建议书写,为什么?
效率很低,因为看似简单的语句 i7 + "",但实际所做的操作是 new Integer(i7).toString() + "" 。简单类型数据转换为 String 类型时,创建包装类对象,再调用了对应包装类的 toString() 方法才能完成。
以下是 8 种简单类型对应的包装类型:
| 简单类型 | 对应的包装类型 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| char | Character |
| boolean | Boolean |
| float | Float |
| double | Double |
包装类从名称上来看,基本上是简单类型名首字母大写就是包装类名了,不过有两个例外,那就是 int --> Integer 和 char --> Character 。
所有的包装类都是在 java.lang 包下的
包装类基本使用
包装类型中最常用的是 Integer。
装箱
既然 Integer 是引用类型,那么它应该是以对象的形式而存在,我们首先会想到的是通过 new + 构造器的方式创建对象。
没错,我们来看一下 Integer 提供的构造器主要是以下两个:
public Integer(int value)public Integer(String s)
因为这个是int包装类,所以字符串数据,双引号中也需要是整型数值,否则无法进行转换操作。
Integer 对象的创建,还可以使用 API 中提供的静态方法:
public static Integer valueOf(int i)public static Integer valueOf(String s)
以上两种方式,完成了整型数据转为包装类型数据,和字符串类型数据转换为包装类型数据,这种行为我们称之为装箱。 😮
拆箱
引用类型,同样也可以让它们转换为简单类型。
public int intValue()
调用 intValue() 方法让 Integer 类型转换为 int 类型数据
这里提到一个非常常用的静态方法,可以将字符串转换为 int 类型:
public static int parseInt(String s)
以上两种方式,完成包装类型转换为简单类型,字符串类型转换为简单类型,这种行为我们称之为拆箱。 😮
自动装箱(基本类型变成包装类型,底层是valueOf)
Integer i1 = 100;
System.out.println(i1);
100 为 int 类型数据,直接赋值给 Integer 类型变量 i1 ,并创建了对象,这就是自动装箱,一般我们也是建议采用这种方式进行书写。打印 i1 ,其实也是打印 i1.toString() ,包装类中的 toString() 方法就是重写了 Object 类中的 toString() 方法。
自动拆箱(包装类型变成基本类型,底层是intValue)
int i2 = i1;
System.out.println(i2);
将 Integer 类型的变量 i1 赋给 int 类型变量 i2,这就是在完成自动拆箱。
关于装箱
该方法里面有一个缓冲区[-128,127],如果装箱数字在范围里面,去常量池取,如果不在,就new一个 我们来看看下面这段代码:
Integer i3 = 127;
Integer i4 = 127;
System.out.println(i3 == i4);
打印输出的结果是什么? 正确答案是 true,为什么呢?
Integer 有一个特殊性,和 String 类很相似,也就是直接给 Integer 赋值,它会先去常量池中查找有没有这个值,有的话就不用申请了,直接指向即可;没有相同的值,再进行申请操作。所以上面的代码中,i3 == i4 它们指向的是同一个地址空间,所以结果为「true」。
Integer i5 = 128;
Integer i6 = 128;
System.out.println(i5 == i6);
超出范围了,以上语句输出的结果则为「false」。
数值计算和比较
可以自动拆箱处理操作。
int i7 = 20;
System.out.println(i7 < i3);
System.out.println(i6 + 30);
i7 是简单类型,而 i3 是引用类型,然而 i3 自动拆箱转换为 int 类型,和 i7 进行值比较,所以结果为「true」;i6 + 30 语句也是同理,i6 自动拆箱为 int 类型进行计算操作。