原帖地址:http://www.ticmy.com/?p=110
jdk1.5引入了自动装箱(autoboxing)与自动拆箱(unboxing),这方便了集合类以及一些方法的调用,同时也使初学者对其感到非常之困惑。在此,我们来揭开其神秘的面纱。
首先,需要厘清一些概念:
1、Integer是一个类,用Integer声明一个变量其是一个对象类型(或者说引用类型);int是基本类型,用int声明的变量是非对象类型,即不能在其上调用方法。
2、“==”作用于对象上的时候,其比较的是对象的引用本身的值(或者说对象的地址更容易理解),而作用于基本类型的时候比较的就是基本类型的值。
接下来看一段代码:
public class Test {
public static void main(String[] args) {
Integer i1 = 2 ;
int i2 = 2 ;
System.out.println(i1 == i2);
}
} |
在这段代码中有两个令人困惑的问题,首先是将一个基本类型的值赋值给对象的引用,即Integer i1 =2;其次是拿一个对象类型和一个基本类型比较。按理说这两种做法肯定都是有问题的,在jdk1.4(若使用的jdk版本是1.5或之后的版本中,可以使用javac -source 1.4 Test.java来编译)上,确实如此,第一个问题在编译时会报“不兼容的类型”错误,第二个问题会报“运算符 == 不能应用于 java.lang.Integer,int”的错误。
但是jdk1.5引入的自动装箱和自动拆箱,那么,必然要将其中的一种类型转换成另一种类型,究竟是将Integer对象i1转换成int基本类型呢?还是将int基本类型的i2转换成Integer对象?通过javap -c Test反编译Test.class文件就知道答案了:
public static void main(java.lang.String[]);
Code:
0 : iconst_2
1 : invokestatic # 2 ; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4 : astore_1
5 : iconst_2
6 : istore_2
7 : getstatic # 3 ; //Field java/lang/System.out:Ljava/io/PrintStream;
10 : aload_1
11 : invokevirtual # 4 ; //Method java/lang/Integer.intValue:()I
14 : iload_2
15 : if_icmpne 22
18 : iconst_1
19 : goto 23
22 : iconst_0
23 : invokevirtual # 5 ; //Method java/io/PrintStream.println:(Z)V
26 : return
} |
其中,[0-4]是Integer i1 = 2的实现,我们发现,编译的字节码里调用了Integer.valueOf方法,因此Integer i1 = 2编译后就等同于Integer i1 = Integer.valueOf(2);[5,6]是int i2 = 2的实现;[7,23]是System.out.println(i1 == i2)的实现,也容易看到,里面调用了Integer.intValue()方法。因此,这个i1 == i2这两个不同类型的变量比较,在编译的时候,编译器是将其转换成相同的类型进行比较的,即将对象类型转换成基本类型,System.out.println(i1 == i2)就等同于System.out.println(i1.intValue() == i2),前面说了,“==”作用于基本类型的时候比较的就是基本类型的值,两个值都是2,所以结果是true。
另外一个令人困惑的例子就是:
public class Test {
public static void main(String[] args) {
Integer i1 = 127 ;
Integer i2 = 127 ;
System.out.println(i1 == i2);
Integer i3 = 128 ;
Integer i4 = 128 ;
System.out.println(i3 == i4);
}
} |
运行后发现,i1==i2的结果为true,i3==i4的结果为false?这令不知原因的人头疼不已。在前面一个例子里我们已经说过,诸如Integer i1 = 127,在编译后就等同于Integer i1 = Integer.valueOf(127),既然是调用一个方法来获得对象,那么就有必要对valueOf方法一探究竟了。我们看下源码:
public static Integer valueOf( int i) {
final int offset = 128 ;
if (i >= - 128 && i <= 127 ) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
} |
到此应该恍然大悟了,IntegerCache缓存了[-128,127]之间的Integer对象,如果valueOf的参数i处于这之间,就返回缓存的对象。否则就new一个新的Integer。前面已经说过,“==”作用于对象上的时候,其比较的是对象的地址,例子中的i1和i2都是从缓存中拿的,当然是同一个对象,i3和i4都是通过new Integer获得的,当然不是同一个对象了。
类似地,java.lang.Long,java.lang.Short分别缓存了[-128,127]之间的Long和Short对象,java.lang.Byte缓存了所有的对象,java.lang.Character缓存了[0,127]之间的Character对象。java缓存这些对象是为了性能优化,既然我们已经知道其缓存了这么些对象,在需要new Integer/Long/…的地方,可改用Integer/Long/Short…#valueOf方法。
但是:
使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN参数即可将Integer的自动缓存区间设置为[-128,NNN]。注意区间的下界固定在-128不可配置。
在client模式下该参数无效。这个参数是server模式专有的,在c2_globals.hpp中声明,默认值是128;不过这个默认值在默认条件下不起作用,要手动设置它的值或者是开启-XX:+AggressiveOpts参数才起作用。
相关推荐
base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz
wincc SIMATIC WinCC是第一个使用最新的32位技术的过程监视系统,具有良好的开放性和灵活性。 从面市伊始,用户就对SIMATIC WinCC印象深刻。
5152单片机proteus仿真和源码INT0与INT1中断计数提取方式是百度网盘分享地址
ZZ-2021030 网络搭建与应用赛项赛卷《网络环境》.pdf
ZZ561401.CAB ZZ561401.CAB ZZ561401.CAB
ZZ-2022015 液压与气动系统装调与维护赛项赛题 中职赛项 适合正在准备技能大赛的人群
在CAD中想要快速测量长度,在CAD工具栏找到加载应用程序,再点击加载 加载成功后在输入栏输入“zz”(不分大小写)在选择你需要测量的线段即可。
我们将我们的预测与NNLO的总包容性横截面的现有结果进行了比较,并找到了很好的协议。 然后,我们为两种实验设置提供了差分分布的结果,一种用于搜索异常三重玻色子玻色子耦合,另一种用于希格斯分析中的四个带电...
ZZ-2022006 建筑智能化系统安装与调试赛项赛题. 中职赛项 适合正在准备技能大赛的人群
ZZ-2022018 制冷与空调设备组装与调试赛项赛题 中职赛项 适合正在准备技能大赛的人群
,主图指标,顶底信号,突破,转折信号,都很明显
介绍了ZZ18000/25.5/50型四柱支撑掩护式支架的主要技术参数、结构特点以及该支架作为快速搬家专用巷道支护支架在回撤巷道中的应用。该支架可实现对回撤巷道的提前支护,缩短了搬家倒面的时间,提高了综采设备的利用率...
一维量子XX-ZZ模型的关联函数与协作参量,钟鸣,,采用把一维量子XX-ZZ模型映射到周期XY模型的方法,数值研究了该模型的关联函数及量子相变类型,以及协作参量在相变点附近的行为。�
ZZ-2022019 电气安装与维修赛项赛题 中职赛项 适合正在准备技能大赛的人群
层号定义,与PADS类似:1~120是etch ;SolderMask: 121(top) 128(bot) ;Silkscreen: 126(top) 129(bot) ;Assembly: 127(top) 130(bot) ;PasteMask: 123(top) 122(bot) ;Display 125(top) 124(bot)
ZZ016网络建设与运维赛项竞赛方案及赛项规程(SW1)
ZZ-2022032 智能家居安装与维护赛项赛题.zip 中职赛项 适合正在准备技能大赛的人群
留言本改自柏图留言本 BTB 1.2 管理员:zz809 密 码:zz809.com
程序员的编辑器——VIM(zz) - 饮水思源
我的资源zzzzzzzzzzzzz