关于包装类的知识

134 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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 种简单类型对应的包装类型:

简单类型对应的包装类型
byteByte
shortShort
intInteger
longLong
charCharacter
booleanBoolean
floatFloat
doubleDouble

包装类从名称上来看,基本上是简单类型名首字母大写就是包装类名了,不过有两个例外,那就是 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 类型进行计算操作。