`

(ZZ)Integer与int解惑

    博客分类:
  • Java
 
阅读更多

原帖地址: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
   19goto    23
   22:  iconst_0
   23:  invokevirtual   #5; //Method java/io/PrintStream.println:(Z)V
   26return
}

其中,[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参数才起作用。

更多信息http://rednaxelafx.iteye.com/blog/680746

分享到:
评论

相关推荐

    base zz zz zz zz

    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中断计数

    5152单片机proteus仿真和源码INT0与INT1中断计数提取方式是百度网盘分享地址

    ZZ-2021030 网络搭建与应用赛项赛卷《网络环境》.pdf

    ZZ-2021030 网络搭建与应用赛项赛卷《网络环境》.pdf

    ZZ561401.CAB

    ZZ561401.CAB ZZ561401.CAB ZZ561401.CAB

    wincc AX NF ZZ

    wincc SIMATIC WinCC是第一个使用最新的32位技术的过程监视系统,具有良好的开放性和灵活性。 从面市伊始,用户就对SIMATIC WinCC印象深刻。

    zz CAD快速计算长度插件

    在CAD中想要快速测量长度,在CAD工具栏找到加载应用程序,再点击加载 加载成功后在输入栏输入“zz”(不分大小写)在选择你需要测量的线段即可。

    超出NLO QCD的高横向动量的ZZ产生

    我们将我们的预测与NNLO的总包容性横截面的现有结果进行了比较,并找到了很好的协议。 然后,我们为两种实验设置提供了差分分布的结果,一种用于搜索异常三重玻色子玻色子耦合,另一种用于希格斯分析中的四个带电...

    8051Proteus仿真c源码INT0及INT1中断计数

    ### 8051 Proteus 仿真 C 源码 INT0 及 INT1 中断计数 在探讨“8051 Proteus 仿真 C 源码 INT0 及 INT1 中断计数”这一主题之前,我们首先需要了解几个基本概念:8051 微控制器、Proteus 仿真平台以及中断(INT)的...

    ZZ016网络建设与运维赛项竞赛方案及赛项规程(SW1)

    ZZ016网络建设与运维赛项竞赛方案及赛项规程(SW1)

    ZZ_MODIFIED_GEEBINF.ENS.zip endnote的样式文件

    Endnote软件不仅能够管理文献,还可以批量下载文献、整理文献库、自动生成参考文献列表,以及与Word等文字处理软件无缝集成,帮助用户在撰写论文时轻松引用文献。 在实际使用中,用户首先需要解压“ZZ_MODIFIED_...

    Zz归零.LSP

    cad标高归零,好用的

    ZZ-2022018 制冷与空调设备组装与调试赛项赛题.zip

    "ZZ-2022018 制冷与空调设备组装与调试赛项赛题"正是这样一个针对中职学生的专业赛事,旨在提升学生的实践操作能力和理论知识水平。 赛题的核心内容涵盖以下几个关键知识点: 1. **制冷原理**:参赛者需要了解并...

    中医大夫助理信息系统 zz-doctor

    Activity是用户界面的主要构成部分,Service用于后台运行任务,BroadcastReceiver处理系统广播事件,而ContentProvider则负责数据的存储与共享。了解并熟练掌握这些组件的用法,对于构建功能完善的Android应用至关...

    ZZ18000/25.5/50型四柱支撑掩护式支架的研制与应用

    5. 顶梁和底座的比压:顶梁对顶板的比压为2.25 MPa,底座对底板的比压为3.16 MPa,确保了支架与巷道地面的稳定接触。 6. 操纵方式:本架手动控制,便于操作。 7. 运输尺寸:6060mm×1650mm×2550mm,方便在巷道内...

    ZZ-2022006 建筑智能化系统安装与调试赛项赛题.zip

    《ZZ-2022006 建筑智能化系统安装与调试赛项赛题》 本赛题主要针对中职学生,旨在提升他们在建筑智能化领域的专业技能和实践能力。建筑智能化系统安装与调试赛项是现代建筑业的重要组成部分,随着科技的发展,智能...

    ZZ Fibo Trader - MetaTrader 5EA.zip

    在ZZ Fibo Trader中,抛物线止损系统与斐波那契分析相结合,可以在价格走势符合预期时保护盈利,同时在市场反转时减少损失。 ZZFiboTrader.mq5 文件是ZZ Fibo Trader EA的核心源代码,采用MQL5语言编写。MQL5是...

    3_Level_ZZ_Semafor.zip_3 level_zz_3_Level_ZZ_semafor_ZZ Semafor_

    ,主图指标,顶底信号,突破,转折信号,都很明显

    zz809.com留言本

    2. **后端逻辑文件**:可能包含PHP或ASP等服务器端脚本,用于处理用户的请求,验证数据,以及与数据库交互。 3. **数据库文件**:如SQL文件,可能包含了留言数据的结构和初始数据,用于快速部署和测试。 4. **配置...

    ZZ-2022031 计算机检测维修与数据恢复赛项赛题.xlsx

    ZZ-2022031 计算机检测维修与数据恢复赛项赛题 中职赛项 适合正在准备技能大赛的人群

Global site tag (gtag.js) - Google Analytics