原帖地址: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
5152单片机proteus仿真和源码INT0与INT1中断计数提取方式是百度网盘分享地址
ZZ-2021030 网络搭建与应用赛项赛卷《网络环境》.pdf
ZZ561401.CAB ZZ561401.CAB ZZ561401.CAB
wincc SIMATIC WinCC是第一个使用最新的32位技术的过程监视系统,具有良好的开放性和灵活性。 从面市伊始,用户就对SIMATIC WinCC印象深刻。
在CAD中想要快速测量长度,在CAD工具栏找到加载应用程序,再点击加载 加载成功后在输入栏输入“zz”(不分大小写)在选择你需要测量的线段即可。
我们将我们的预测与NNLO的总包容性横截面的现有结果进行了比较,并找到了很好的协议。 然后,我们为两种实验设置提供了差分分布的结果,一种用于搜索异常三重玻色子玻色子耦合,另一种用于希格斯分析中的四个带电...
### 8051 Proteus 仿真 C 源码 INT0 及 INT1 中断计数 在探讨“8051 Proteus 仿真 C 源码 INT0 及 INT1 中断计数”这一主题之前,我们首先需要了解几个基本概念:8051 微控制器、Proteus 仿真平台以及中断(INT)的...
ZZ016网络建设与运维赛项竞赛方案及赛项规程(SW1)
Endnote软件不仅能够管理文献,还可以批量下载文献、整理文献库、自动生成参考文献列表,以及与Word等文字处理软件无缝集成,帮助用户在撰写论文时轻松引用文献。 在实际使用中,用户首先需要解压“ZZ_MODIFIED_...
cad标高归零,好用的
"ZZ-2022018 制冷与空调设备组装与调试赛项赛题"正是这样一个针对中职学生的专业赛事,旨在提升学生的实践操作能力和理论知识水平。 赛题的核心内容涵盖以下几个关键知识点: 1. **制冷原理**:参赛者需要了解并...
Activity是用户界面的主要构成部分,Service用于后台运行任务,BroadcastReceiver处理系统广播事件,而ContentProvider则负责数据的存储与共享。了解并熟练掌握这些组件的用法,对于构建功能完善的Android应用至关...
5. 顶梁和底座的比压:顶梁对顶板的比压为2.25 MPa,底座对底板的比压为3.16 MPa,确保了支架与巷道地面的稳定接触。 6. 操纵方式:本架手动控制,便于操作。 7. 运输尺寸:6060mm×1650mm×2550mm,方便在巷道内...
《ZZ-2022006 建筑智能化系统安装与调试赛项赛题》 本赛题主要针对中职学生,旨在提升他们在建筑智能化领域的专业技能和实践能力。建筑智能化系统安装与调试赛项是现代建筑业的重要组成部分,随着科技的发展,智能...
在ZZ Fibo Trader中,抛物线止损系统与斐波那契分析相结合,可以在价格走势符合预期时保护盈利,同时在市场反转时减少损失。 ZZFiboTrader.mq5 文件是ZZ Fibo Trader EA的核心源代码,采用MQL5语言编写。MQL5是...
,主图指标,顶底信号,突破,转折信号,都很明显
2. **后端逻辑文件**:可能包含PHP或ASP等服务器端脚本,用于处理用户的请求,验证数据,以及与数据库交互。 3. **数据库文件**:如SQL文件,可能包含了留言数据的结构和初始数据,用于快速部署和测试。 4. **配置...
ZZ-2022031 计算机检测维修与数据恢复赛项赛题 中职赛项 适合正在准备技能大赛的人群