Java自动装箱与拆箱及其陷阱分析_第1页
Java自动装箱与拆箱及其陷阱分析_第2页
Java自动装箱与拆箱及其陷阱分析_第3页
Java自动装箱与拆箱及其陷阱分析_第4页
Java自动装箱与拆箱及其陷阱分析_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Java自动装箱与拆箱及其陷阱分析 本文档格式为WORD,感谢你的阅读。 最新最全的 学术论文 期刊文献 年终总结 年终报告 工作总结 个人总结 述职报告 实习报告 单位总结 演讲稿Java自动装箱与拆箱及其陷阱分析Java中一个非常重要也非常有趣的特性,就是自动装箱与拆箱,本文是YJBYS小编搜索整理的关于Java自动装箱与拆箱及其陷阱分析,给大家做个参考,希望对大家有所帮助!想了解更多相关信息请持续关注我们!自动装箱(Autoboxing)大家在平时编写Java程序时,都常常以以下方式来定义一个Integer对象:Integer i=100;从上面的代码中,大家可以得知,i为一个Integ

2、er类型的引用,100为Java中的基础数据类型(primitive data type)。而这种直接将一个基础数据类型传给其相应的封装类(wrapper class)的做法,便是自动装箱(Autoboxing)。在jdk 1.5中,自动装箱首次被引入。而在jdk 1.5之前,如果你想要定义一个value为100的Integer对象,则需要这样做:Integer i=new Integer (100);我们在以上代码“Integer i=100;”处打一个断点,跟踪一下。接下来,我们可以看到,程序跳转到了Integer类的valueOf(int i)方法中/* Returns a lt;ttg

3、t;Integerlt;/ttgt; instance representing the specifiedlt;ttgt;intlt;/ttgt; value.* If a new lt;ttgt;Integerlt;/ttgt; instance is not required, this method* should generally be used in preference to the constructor* link #Integer(int), as this method is likely to yield* significantly better space and

4、 time performance by caching* frequently requested values.* param i an lt;codegt;intlt;/codegt; value.* return a lt;ttgt;Integerlt;/ttgt; instance representing lt;ttgt;ilt;/ttgt;.* since 1.5public static Integer valueOf(int i) if(i gt;= -128 amp;amp; i lt;= IntegerCache.high)return IntegerCache.cach

5、ei + 128;elsereturn new Integer(i);换句话说,装箱就是jdk自己帮你完成了调用Integer.valueOf(100)。拆箱(Unboxing)Integer integer100=100;int int100=integer100;从上面的代码中,大家可看出integer100为一个Integer类型的引用,int100为一个int类型的原始数据类型。但是,我们可以将一个Integer类型的对象赋值给其相应原始数据类型的变量。这便是拆箱。拆箱与装箱是相反的操作。装箱是将一个原始数据类型赋值给相应封装类的变量。而拆箱则是将一个封装类的变量赋值给相应原始数据类型

6、的变量。装箱、拆箱的名字也取得相当贴切。笔者相信大家也都猜到了,拆箱过程中jdk为我们做了什么。我们还是通过实验来证明我们的猜想吧。在以上代码的第二行代码打上断点,即在“int int100=integer100;”上打上断点,跟踪一下。我们可以看到,程序跳转到了Integer的intValue()方法。/* Returns the value of this lt;codegt;Integerlt;/codegt; as anlt;codegt;intlt;/codegt;.public int intValue() return value;也就是,jdk帮我们完成了对intValue()

7、方法的调用。对于以上的实验而言,便是调用integer100的intValue()方法,将其返回值赋给了int100。扩展实验1Integer integer400=400;int int400=400;System.out.println(integer400=int400);在以上代码的第三行中,integer400与int400执行了=运行。而这两个是不同类型的变量,到底是integer400拆箱了,还是int400装箱了呢?运行结果是什么呢?=运算是判断两个对象的地址是否相等或者判断两个基础数据类型的值是否相等。所以,大家很容易推测到,如果integer400拆箱了,则说明对比的是两个

8、基础类型的值,那此时必然相等,运行结果为true;如果int400装箱了,则说明对比的是两个对象的地址是否相等,那此时地址必然不相等,运行结果为false。(至于为什么笔者对它们赋值为400,就是后面将要讲到的陷阱有关)。我们实际的运行结果为true。所以是integer400拆箱了。对代码跟踪的结果也证明这一点。实验2Integer integer100=100;int int100=100;System.out.println(integer100.equals(int100);在以上代码的第三行中,integer100的方法equals的参数为int100。我们知道equals方法的参数

9、为Object,而不是基础数据类型,因而在这里必然是int100装箱了。对代码跟踪的结果也证明了这一点。其实,如果一个方法中参数类型为原始数据类型,所传入的参数类型为其封装类,则会自动对其进行拆箱;相应地,如果一个方法中参数类型为封装类型,所传入的参数类型为其原始数据类型,则会自动对其进行装箱。实验3Integer integer100 = 100;int int100 = 100;Long long200 = 200l;System.out.println(integer100 + int100);System.out.println(long200 = (integer100 + int1

10、00);System.out.println(long200.equals(integer100 + int100);在第一个实验中,我们已经得知,当一个基础数据类型与封装类进行=运算时,会将封装类进行拆箱。那如果+、-、*、/呢?我们在这个实验中,就可知道。如果+运算,会将基础数据类型装箱,那么:?第4行中,integer100+int100就会得到一个类型为Integer且value为200的对象o,并执行这个对象的toString()方法,并输出”200”;?第5行中,integer100+int100就会得到一个类型为Integer且value为200的对象o,=运算将这个对象与lon

11、g200对象进行对比,显然,将会输出false;?第6行中,integer100+int100就会得到一个类型为Integer且value为200的对象o,Long的equals方法将long200与o对比,因为两都是不同类型的封装类,因而输出false;如果+运算,会将封装类进行拆箱,那么:?第4行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b,再将b进行装箱得到o,执行这个对象的toString()方法,并输出”200”;?第5行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b1,=运算将

12、long200进行拆箱得到b2,显然b1=b2,输出true;?第6行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b,Long的equals方法将b进行装箱,但装箱所得到的是类型为Integer的对象o,因为o与long200为不同的类型的对象,所以输出false;程序运行的结果为:200truefalse因而,第二种推测是正确,即在+运算时,会将封装类进行拆箱。陷阱陷阱1Integer integer100=null;int int100=integer100;这两行代码是完全合法的,完全能够通过编译的,但是在运行时,就会抛出空指针异常。其

13、中,integer100为Integer类型的对象,它当然可以指向null。但在第二行时,就会对integer100进行拆箱,也就是对一个null对象执行intValue()方法,当然会抛出空指针异常。所以,有拆箱操作时一定要特别注意封装类对象是否为null。陷阱2Integer i1=100;Integer i2=100;Integer i3=300;Integer i4=300;System.out.println(i1=i2);System.out.println(i3=i4);因为i1、i2、i3、i4都是Integer类型的,所以我们想,运行结果应该都是false。但是,真实的运行结

14、果为“System.out.println(i1=i2);”为 true,但是“System.out.println(i3=i4);”为false。也就意味着,i1与i2这两个Integer类型的引用指向了同一个对象,而i3与i4指向了不同的对象。为什么呢?不都是调用Integer.valueOf(int i)方法吗?让我们再看看Integer.valueOf(int i)方法。/* Returns a lt;ttgt;Integerlt;/ttgt; instance representing the specifiedlt;ttgt;intlt;/ttgt; value.* If a ne

15、w lt;ttgt;Integerlt;/ttgt; instance is not required, this method* should generally be used in preference to the constructor* link #Integer(int), as this method is likely to yield* significantly better space and time performance by caching* frequently requested values.* param i an lt;codegt;intlt;/co

16、degt; value.* return a lt;ttgt;Integerlt;/ttgt; instance representing lt;ttgt;ilt;/ttgt;.* since 1.5public static Integer valueOf(int i) if(i gt;= -128 amp;amp; i lt;= IntegerCache.high)return IntegerCache.cachei + 128;elsereturn new Integer(i);我们可以看到当igt;=-128且ilt;=IntegerCache.high时,直接返回IntegerCac

17、he.cachei + 128。其中,IntegerCache为Integer的内部静态类,其原码如下:private static class IntegerCache static final int high;static final Integer cache;static final int low = -128;/ high value may be configured by propertyint h = 127;if (integerCacheHighPropValue != null) / Use Long.decode here to avoid invoking met

18、hods that/ require Integer#39;s autoboxing cache to be initializedint i = Long.decode(integerCacheHighPropValue).intValue();i = Math.max(i, 127);/ Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - -low);high = h;cache = new Integer(high - low) + 1;int j = low;for(int k = 0; k lt; cache.length; k+)cachek = new Integer(j+);private IntegerCache() 我们可以清楚地看到,IntegerCache有静态成员变量cache,为一个拥有256个元素的数组。在IntegerCache中也对cache进行了初始化,即

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论