美文网首页
装箱与拆箱详解笔记

装箱与拆箱详解笔记

作者: Timor小先生 | 来源:发表于2020-04-27 15:09 被阅读0次

1、什么是自动装箱与拆箱

//自动装箱

Integer integer = 100;

//自动拆箱

int i = integer;

装箱:自动将基本类型转化为包装类

拆箱:自动将包装类转化为基本类型

2、基本原理

(1)、自动装箱,valueOf()

Integer integer = 100  时系统自动执行了  Integer integer = Integer.valueOf(100);

Integer.valueOf  源码

static final int low = -128;

static final int high;

static final Integer cache[];

public static Integer valueOf(int i) {

    if (i >= IntegerCache.low && i <= IntegerCache.high)

          return IntegerCache.cache[i + (-IntegerCache.low)];

    return new Integer(i);

}

首先判断i大小,是否在low (-128) 与high (默认127) 之间,不在就新创建一个Integer对象,否则返回cache数组。

这里注意:

a、在某个范围内的整型数值的个数是有限的,而浮点数却不是。所以Double Float不会有数组出现。

b、cache 是一个静态的Integer数组,也就是说如果在low与high之间,返回的都是一个integer对象。

c、装箱过程会创建相应的对象,会消耗内存,影响性能。

(2)、自动拆箱,intValue()

int i = integer  时系统自动执行了  int i = integer.intValue();

intValue 源码

public int intValue() {

    return value;

}

3、相关问题

(1)、自动装箱 ==  问题

a、Integer在 (-127,128] 有限个数

Integer integer1 = 100;

Integer integer2 = 100;

Integer integer3 = 200;

Integer integer4 = 200;

System.out.println(integer1 == integer2); //true

System.out.println(integer3 == integer4); //false

这里都会进行自动装箱,但是 integer1、integer2 因为在-127到128 范围内,所以返回了同一个Integer对象,所以他们是相等的

integer3、integer4也会进行自动封箱,但是因超出范围,都会返回 new Integer(200) ,所以不相等。

b、Double类型

Double aDouble1 = 100.0;

Double aDouble2 = 100.0;

Double aDouble3 = 100.0;

Double aDouble4 = 100.0;

System.out.println(aDouble1 == aDouble2); //false

System.out.println(aDouble3 == aDouble4); //false

这里和Integer不太一样,因为valueOf的实现不一样,对于Integer在某个范围内个数有限,所以为避免多次创建对象,java8会直接创建好一个大小为256的Integer数组,如果在这个范围内,直接返回这个对象。

但是Double,在这个范围内是无限的,所以只能每次都新创建一个对象。类似的还有Float。

c、Boolean

对于Boolean类型,只有两种情况,所以都是提前创建好的,这样也是为了避免创建过多对象。

(2)、Integer.equals(int) 问题

Integer i1 = 10;

int i2 = 10;

System.out.println(i1 == i2); //true

System.out.println(i1.equals(i2)); //true

对于 == 操作,i1会进行自动拆箱

对于 equals 操作,传入的是int,但源码参数是Object类型,所以会进行自动封箱,返回 true 是因为比较的是对象里的值,这里是重写了Object里面的 equals 方法,若不重写 equals 方法则比较的是引用对象的对象地址。

public boolean equals(Object obj) {

    if (obj instanceof Integer) {

        return value == ((Integer)obj).intValue();

    }

    return false;

}

(3)、不同类型数值 == 与 equals 问题

Integer num1 = 1;

int num2 = 1;

Long num3 = 2l;

System.out.println(num1 + num2); //2

System.out.println(num3 == (num1 + num2)); //true

System.out.println(num3.equals(num1 + num2)); //false

首先进行+ - * / == 运算会进行拆箱,进行基本数据类型之间运算、比较。

equals 返回 false 是因为在比较 equals 时会进行自动封箱,只有当类型相同、内容相同时才返回true。

(4)、不同类型不涉及基本类型比较 == 

Integer num1 = 100;

Ingeger num2 = 200;

Long num3 = 300l;

System.out.println(num3 == (num1 + num2)); //true

进行 == 时 num3 进行拆箱,num1 + num2 进行拆箱

(5)、基本类型测试

int num1 = 100;

int num2 = 200;

long mum3 = 300;

System.out.println(num3 == (num1 + num2)); //true

对 (4) 的解释,基本类型比较的是数值

所以,当 “==”运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

(6)、包装类可以初始化为null,在进行拆箱时会报空指针异常

Integer integer = null;

int i = integer;

所以有拆箱操作的时候要注意是否为null。

4、总结一下:

拆箱:包装类型 ----> 基本类型 ----> ==、运算

装箱:基本类型 ----> 包装类型 ----> equals

相关文章

网友评论

      本文标题:装箱与拆箱详解笔记

      本文链接:https://www.haomeiwen.com/subject/dwtywhtx.html