目录
- 一、什么是包装类
- 1、八大基本数据类型
- 2、包装类定义
- 3、为什么会有包装类
- 二、装箱和拆箱
- 1、自动装箱
- 2、自动拆箱
- 3、包装类习题
- 三、128陷阱
一、什么是包装类
1、八大基本数据类型
整形:byte(1字节)、short(2字节)、int(4字节)、long(8字节)
浮点型:float(4字节)、double(8字节)
布尔型:boolean(4字节)
字符型:根据情况所确定
2、包装类定义
包装类是java中的一种特殊的类,用于将基本数据类型转换为对应的对象。每个基本的数据类型都有对应的包装类。
基本数据类型和包装类的对应关系如下:
int -> Integer
short -> Short
byte -> Byte
long -> Long
double -> Double
float -> Float
char - > Character
boolean -> Boolean
3、为什么会有包装类
Java 号称“万物皆对象”,但 八大基本数据类型(Primitive Types) 不是对象,而是直接存储在 栈内存 中的值类型。为了:
(1)让基本类型也能以对象形式操作(如存入集合List)。
(2)提供更多的功能方法(如 Integer.parseInt())。
(3)支持泛型(泛型只能接受对象类型,如 List 不合法,必须用 List)。
二、装箱和拆箱
1、自动装箱
引用数据类型的创建新对象的时候通常需要用到new,但是包装类的底层实现了自动装箱,可以直接赋值就可以实现。
Integer a = 1;Integer b = Integer.valueOf(1);
2、自动拆箱
包装类对象处于需要用于基本数据类型的时候,会自动拆箱转变为基本数据类型,使用 Interger.intValue(),进行拆箱,包装类底层可以自动实现。
Integer a = 1;Integer b = Integer.valueOf(1);int k = b;int c = 1;System.out.println(c == a);System.out.println(c == b);
当 基本数据类型和引用数据类型进行比较的时候自动拆箱
3、包装类习题
public static void main(String[] args) {int a = 10;int b = 10;Integer a1 = 10;Integer b1 = 10;Integer a2 = new Integer(10);Integer b2 = new Integer(10);System.out.println(a == b); System.out.println(a1 == b1); System.out.println(a2 == b2); System.out.println(a1 == a); System.out.println(a1.equals(a)); System.out.println(a1 == a2);System.out.println(a == a2);
}
结果以及分析如下:
1、
System.out.println(a == b);
分析: a和b都是基本数据类型,== 比的是 变量名存的值,所以 输出true
2、
System.out.println(a1 == b1);
分析:a1和a2都是Integer类型的我们可以查看Integer底层的代码。
IntegerCache.low 是 -128 IntegerCache.high是127
上面的代码的意思是当值位于 (-128 - 127)范围内,会把数组中定义好的Integer对象返回。 因为上面 a1 和a2 指向相同的空间 具有相同的内存地址 引用数据类型比较的又是内存地址,所以a1 和 a2 相同。
3、
System.out.println(a2 == b2);
分析:a2是数组中new Integer()的对象,b2 是新new出来的Integer()对象,重新生成一个对象会提供一个新的内存地址,所以 a2 和 b2 不相同。
4、
System.out.println(a1 == a);
分析:a1是数组中的new出来的对象,但是a是基本数据类型,但是 包装类 会在 == 的时候自动完成拆箱的操作
5、
System.out.println(a1.equals(a));
分析:Integer重写的equals,重写的equals方法实现了拆箱的操作,也会比较数值的大小但是 包装类 会在 == 的时候自动完成拆箱的操作
6、
System.out.println(a1 == a2);
分析:a1是的new出来的对象,a2也是new出来的对象,所以内存地址不同,返回false
7、
System.out.println(a == a2);
分析:a2是数组中的new出来的对象,但是a是基本数据类型,但是 包装类 会在 == 的时候自动完成拆箱的操作。
三、128陷阱
128陷阱是原来典型的面试题,考察了Integer底层的逻辑, 典型的形式是下面代码的情况:
Integer a1 = 127;Integer a2 = 127;Integer a3 = 128;Integer a4 = 128;System.out.println(a1 == a2);System.out.println(a3 == a4);
没听说过 128陷阱的同学,肯定觉得 完成自动装箱之后,都是new Integer()的对象,内存地址肯定不同 所以
false false;
但是实际情况如下:
我们会分析上面的情况,在第二部分我们讲到了:
Integer a1 = 127;Integer a1 = Integer.valueOf(127);
上面的情况1是Integer内部会自动实现情况2的,所以我们会查看Integer.valueOf(127)的源码。
上面的代码是提出了high是127,low是-128。
cache[] 是大小为256的数组解释如下:
解释:
if (i >= IntegerCache.low && i <= IntegerCache.high)
当输入的值大于等于-128小于等于127的时候返回
return IntegerCache.cache[i + (-IntegerCache.low)];
接下来看cache数组中存的是什么:
我们可以看到 j = -128 cache是256大小的数组,而且每一个索引对应的是一个new Integer()对象,所以cache数组中存的是已经定义好的从(-128,127)的Intger对应的值。
所以在一次分析最初的问题,100小于127,200大于127 所以 小于127是从数组中 得到的Integer对象指向相同的内存地址,所以前两个返回true,200是返回的新的Integer对象,所以内存地址不同、