Java自动拆装箱简单介绍
在面试过程中,常常会有面试官问到基础的问题的时候都会问到Java的拆装箱,关于这个问题其实不是很难,但是如果平时进行自学的时候不是注意,就可能一脸懵逼,所以笔者就这个问题进行一些总结,共同促进!
一、拆装箱概念
所谓的拆装箱,就是自从JDK1.5之后,java的基本类型和引用类型之间的相互转换。
1.1拆箱
拆箱就是把Long,Integer,Double,Float等将基本数据类型的首字母大写的相应的引用类型转化为基本数据类型的动作就叫拆箱。
1.2装箱
装箱就是把byte,int,short,long,double,float,boolean,char这些Java的基本数据类型在定义数据类型时不声明为相对应的引用类型,在编译器的处理下自动转化为引用类型的动作就叫做装箱。
二、拆装箱的相关应用
在JDK1.5后,当我们进行基本类型和引用类型的转换的时候就会方便:
packagecom.hzp.CZX; /** *测试拆装箱 *@author夜孤寒 *@version1.1.1 */ publicclassTestDemo{ /** *拆装箱JDK1.5后 */ publicstaticvoidfirst(){ Integeri=7;//基本类型-->引用类型 intj=i;//引用类型-->基本类型 System.out.println(j); } /** *拆装箱JDK1.4 */ publicstaticvoidsecond(){ Integeri=newInteger(78); intj=i.intValue(); System.out.println(j); } /** *测试方法 *@paramargs */ publicstaticvoidmain(String[]args){ first(); second(); } }
上面介绍了关于拆装箱的一些基本点和使用方式,但是要使用拆装箱的话还有一些注意点需要注意,下面将这些注意点进行一些总结。
三、注意点
首先贴一段代码如下:
packagecom.ygh.CZX; /** *关于java的拆装箱范围剖析 *@author夜孤寒 *@version1.1.1 */ publicclassTest{ /** *以Integer类型为例 */ publicstaticvoidfirst(){ Integeri=newInteger(124); Integerj=newInteger(124); System.out.println(i==j);//false Integera1=-128; Integera2=-128; System.out.println(a1==a2);//true Integerb1=-129; Integerb2=-129; System.out.println(b1==b2);//false Integerc1=127; Integerc2=127; System.out.println(c1==c2);//true Integerd1=128; Integerd2=128; System.out.println(d1==d2);//false } publicstaticvoidmain(String[]args){ first(); } }
简单解释一下:
第一个结果为false的原因是因为创建了不同的对象,所以两者不一样;
但是第二个和第三个的结果为什么不一样?
下面贴出关于Integer类的源码,从源码的角度来分析这个问题:
/** *Returnsan{@codeInteger}instancerepresentingthespecified *{@codeint}value.Ifanew{@codeInteger}instanceisnot *required,thismethodshouldgenerallybeusedinpreferenceto *theconstructor{@link#Integer(int)},asthismethodislikely *toyieldsignificantlybetterspaceandtimeperformanceby *cachingfrequentlyrequestedvalues. * *Thismethodwillalwayscachevaluesintherange-128to127, *inclusive,andmaycacheothervaluesoutsideofthisrange. * *@paramian{@codeint}value. *@returnan{@codeInteger}instancerepresenting{@codei}. *@since1.5 */ publicstaticIntegervalueOf(inti){ if(i>=IntegerCache.low&&i<=IntegerCache.high) returnIntegerCache.cache[i+(-IntegerCache.low)]; returnnewInteger(i); }
上面的代码是说,进行自动拆装箱的时候,是有一个范围的,一旦超出这个范围,那么指向的就不是同一个对象,而是返回一个新创建的对象了,这个范围在Integer类中的一个内部私有类IntegerCache可以体现出来,源码如下:
privatestaticclassIntegerCache{ staticfinalintlow=-128; staticfinalinthigh; staticfinalIntegercache[]; static{ //highvaluemaybeconfiguredbyproperty inth=127; StringintegerCacheHighPropValue= sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if(integerCacheHighPropValue!=null){ try{ inti=parseInt(integerCacheHighPropValue); i=Math.max(i,127); //MaximumarraysizeisInteger.MAX_VALUE h=Math.min(i,Integer.MAX_VALUE-(-low)-1); }catch(NumberFormatExceptionnfe){ //Ifthepropertycannotbeparsedintoanint,ignoreit. } } high=h; cache=newInteger[(high-low)+1]; intj=low; for(intk=0;k=127; } privateIntegerCache(){} }
从这里我们可以看出,范围值为[-128,127]之间。
注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
总结:这些进行自动拆装箱的基本类型的范围如下:
1.boolean类型的值
2.所有的byte的值
3.在-128~127的short类型的值
4.在-128~127的int类型的值
5.在\u0000~\u00ff之间的char类型的值
而其中double和float又有所不同,我们就以double为例子,贴出代码讨论:
packagecom.ygh.CZX; /** *关于java的拆装箱范围剖析 * *@author夜孤寒 *@version1.1.1 */ publicclassTest{ /** *Double */ publicstaticvoidfirst(){ Doublei1=100.0; Doublei2=100.0; Doublei3=200.0; Doublei4=200.0; System.out.println(i1==i2);//false System.out.println(i3==i4);//false } /** *测试方法 */ publicstaticvoidmain(String[]args){ first(); } }
注意为什么上面的代码的输出结果都是false呢?同样的我们依旧以Double类中的valueOf方法来讨论,贴出源码就一目了然了:
/** *Returnsa{@codeDouble}instancerepresentingthespecified *{@codedouble}value. *Ifanew{@codeDouble}instanceisnotrequired,thismethod *shouldgenerallybeusedinpreferencetotheconstructor *{@link#Double(double)},asthismethodislikelytoyield *significantlybetterspaceandtimeperformancebycaching *frequentlyrequestedvalues. * *@paramdadoublevalue. *@returna{@codeDouble}instancerepresenting{@coded}. *@since1.5 */ publicstaticDoublevalueOf(doubled){ returnnewDouble(d); }
也就是说不管你的double是什么范围的值,他都是给你返回一个新的对象。float同double,就不过多赘述了。
以上就是笔者对于拆装箱的一些整理,如果读者有不同的看法可以在评论区提出,笔者再进行修改!
希望对大家的学习有所帮助,也希望大家多多支持毛票票。