java拆箱和装箱_java的装箱和拆箱详解

=========================================================================================

在我看来,学习java最重要是要理解what(这东西是什么),why(为什么要用它),where(在哪用它),how(怎么用)。所以接下来,我都是以这样的思想来和大家交流,从最基础的知识讲起。如果有啥出错的,欢迎大家前来批评。本人虚心接纳。

=========================================================================================

一.what(什么是装箱和拆箱)

我们前面学过了基本类型int,double这些,那大家肯定也见过引用类型Integer,Double等,是不是长的很像?那究竟有啥区别呢?先来说说概念。

(1).装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float等。

(2).拆箱:和装箱相反,将引用类型的对象简化成值类型的数据。

由此可知,基本类型是没有对象的性质,但是包装过后的包装器类型就具有对象性质,也当然具有更多性质和方法啦。怎么创建一个对象呢?

(3).怎么装箱: 在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行,这个不会触发自动装箱的过程:

3b74660f8346e0cec192a6bfa1aee57a.png

从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了:

c8ad6a229dc504e6d4d395b49b0265db.png

(4).怎么拆箱:跟装箱对应,就是自动将包装器类型转换为基本数据类型

4f83b3c21ffdb7abb927f87555ececaf.png

(5).除了int,还有很多基本类型,每个都有对应的包装型:

3cc2a42f0c90264863524d5ebbffcdd4.png

二.why(为什么要用装箱和拆箱)

(1).把一个基本类型包装成一个类,一个是可以使这个类型具有很多可以调用的方法。

(2).java主要特点是面向对象,基本类型并不具备面向对象特性,所以要把其封装成面向对象的类。

(3).在泛型中,基本类型是不可以做泛型参数的。如:List list = new ArrayList ();这是不合法的。你只能这个样写List list = new ArrayList ();也就是要用int型的包装类类型来解决基本类型不可以做泛型参数的问题 。

三.How(装箱和拆箱是怎么实现的)

(1).在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。

(2).总的来说,装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型,如果是int就是intValue,如果是double就是doubleValue)。

3ad0232d35efc3f9d11863b51092241e.png

4462a796e2ec28ecd1ec9107ce8f15a6.png

四.注意事项

包装类型并没有我们想象的那么简单,面试时候别人最喜欢这样坑人,看例子:

(1).

5db544ffc944ded276d46921f0e2cedb.png

猜测:一看就是比较i1是否等于i2和比较i3是否等于i4,如果相等就输出true,否则false(==号是返回Boolean类型),第一次结果是true,true,明显相等的。然而。。。

3eaf9af37bd6b72f3947d023c6d784b9.png

那么为啥这样??其实是在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache(源码的一个方法)中已经存在的对象的引用;否则创建一个新的Integer对象。上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

(2).如果换成Double呢,看似跟上面一样的,其实并不是

86a7309a9c9ff281a8f721429169911f.png

具体实现,可以去看看源码,理解很简单的,只不过和Integer的实现不一样了。同理,其他的基本类型也是这样的。

(3).

13ca73d6e433a2504f5c453499d1680b.png

Bollean就没有什么特别的,就单纯比较相不相等。

(4).

d0592d55ae129d0141764af92d72c9ca.png

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

解释:按照上面来说,似乎是为false,但是呢结果确实true,为啥呢?因为a,b,c原本都是包装类型,也就是一个对象,当然不能相加减啦,那怎么办?java现在都有了自动装箱和拆箱,当a+b时候,a和b都会自动拆箱为基本类型,所以就成了基本类型的比较了,也就是比较数值相等不相等了,因为c=a+b所以为true.

(5).

3e3527e15cfb06b42e9f2de304e0cb8a.png

解释:c.equals(a+b)会先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,因为equals方法并不会进行类型转换,便调用Integer.valueOf方法,再进行equals比较。

===========================================================================

用心查阅,有心分享,分享之际,互相指教,受益你我,何乐不为?

===========================================================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值