入题
自动封箱与拆箱人人皆可言之道之,但封箱和拆箱却被多数人略之!如此简单的一个机制,却影射着Java的核心理念,不清楚?继续向下看吧~
Java中的数据类别
目前Java中的数据类别分为两种,一种是primitive(原生类型),另一种就是object(对象类型)。提示:从jdk13开始,会引进第三种类型,名为ValueType,设计理念是结合了primitive和object的优点。
primitive包含8种数据类型,它们分别是:short
int
long
float
double
char
byte
boolean
你知道这8种原生的数据类型跟对象在使用上有什么区别吗?为了加深记忆,这里放一张图:
没错!这点你肯定知道的!那就是原生类型在作为参数传递到方法中时使用的是“值传递”的方式,而对象作为参数传递到方法中时使用的是“传引用”的方式。
值传递,意味着传递的是当前值的一个拷贝,而且这个拷贝的生命周期只在当前被传递的方法体内,充其量这个拷贝只是一个临时变量,能让方法体内的其它操作获取到这个值就可以。
至于方法体内对这个值的改变,根本无法反应到方法外的变量中!
而对象传递因为传的是引用,即传的是当前对象的内存地址,所以方法内部对该对象的任何改变都会应用到当前对象所在的内存块中,也就可以实现阶段性的永久改变。
原生类型跟对象类型在传参这块的区别应该是二者在使用上的最大区别!
什么是Java中的包装类?
官方的叫法是Wrapping Class,意思是指原生类型的对象类,这里我简称PWC。那么什么是PWC呢?很简单,JAVA内部对上述的8种原生类型提供了8个对象类,而这8个对象类就是PWC,它们的对应关系如下:
记住这张图就可以了,左边是原生类型primitive,右边是与之对应的对象类型object,如是而已!
为什么要设计出包装类?
其实这个问题是最关键的,只有明白为什么Java要设计出包装类,才能在使用原生类型和对象类型时因地制宜。
理由如下:
第一:如果你想在方法体内更新primitive类型的值,必须要使用primitive对应的object,因为前者使用的值传递,后者使用的是引用传递。
第二:java.util内操作的都是对象,如果没有PWC,会让程序员在使用这些工具类操作primitive类型时编写额外的代码。
第三:Java提供的集合框架中的数据结构,比如ArrayList和Vector,也是只能操作对象,理由跟第二点相似。
第四:多线程中也必须使用对象来完成各种同步操作。
第五:从设计理念上,在Java中,万物皆对象,为primitive类型设计出与之匹配的对象类型,更能让编程体验与设计理念融为一体!
所以,基于上述五点考虑,包装类的存在是有其积极意义的!
包装类的自动化--装箱与拆箱
明白了PWC存在的必要性之后,就需要理解一下JAVA中是如何让primitive和object之间自动转换的。JAVA提供了一种自动化机制,primitive到object叫AutoBoxing(自动装箱),反之叫作Unboxing(拆箱),具体这两种自动化是怎么运作的,先看个例子:
上图中的注释写的很明确了,程序员可以可以使用拆装箱的自动化机制,即primitive和object之间可以混用,java会帮程序员依据方法或类型的实际需要进行内部的拆装箱操作。当然程序员也可以使用手动拆装箱,装箱可以调用object的构造方法或valueOf()方法,拆箱可以调用某个object的xxxValue()方法。提示:不能因为java提供了自动化的拆装箱机制就不再关心primitive和object之间的区别,关键时刻可能由于参数传递的问题而导致让自己骂自己是小白的bug!
结束语
Wrapping Class的核心作用是让primitive类型跟object类型自动融合按需而用,为了方便编程java提供了拆装箱的自动化机制,普通使用可能感觉不出primitive和object之间的差别,但如果用到了jdk提供的工具类或集合类或是涉及到了多线程编程,拆装箱自动化的价值才会显现出来!因为对高级应用而言,它们只处理对象!
---------关于作者----------
Java开发人员,在今日头条开有视频专栏《Java高级加油站》,头条号名称跟知乎名称相同,想看视频专栏的朋友可以去搜索关关注!
-------------------------------------------------------------------------