`

Integer类中使用“==”的问题(内部缓存)

阅读更多

首先看一段代码(使用JDK 5),如下: 

public class Test { 
  public static void main(String[] args) { 
    Integer i1 = 127; 
    Integer i2 = 127; 

    if (i1 == i2) 
      System.out.println("Equal!"); 
    else 
      System.out.println("Not equal!"); 
  } 
} 

 
    输出结果想必大家也知道,是“Equal!”。现在把i1和i2的值由127改为128看看会发生什么?结果输出“Not equal!”。
    这个问题的答案看了下面的就会清楚了。

   为了更容易理解问题,用Jad将上面代码反编译,如下:

import java.io.PrintStream; 

public class Test 
{ 

    public Test() 
    { 
    } 

    public static void main(String args[]) 
    { 
        Integer i1 = Integer.valueOf(128); 
        Integer i2 = Integer.valueOf(128); 
        Integer i3 = Integer.valueOf(128); 

        if(i1 == i2) 
            System.out.println("i1 == i2 is true!"); 
        else 
            System.out.println("i1 == i2 is false!"); 

        if(i1.intValue() >= i2.intValue()) 
            System.out.println("i1 >= i2 is true!"); 
        else 
            System.out.println("i1 >= i2 is false!"); 

        if(i1 == i3) 
            System.out.println("i1 == i3 is true!"); 
        else 
            System.out.println("i1 == i3 is false!"); 
    } 
} 

 

   从这可以看出,“Integer i1 = 127;”在JDK1.5下应该编译成了“Integer i1 = Integer.valueOf(127);”。 

 

    再看看java.lang.Integer中关于valueOf的源代码是怎样的: 

 

  public static Integer valueOf(int i) { 
    final int offset = 128; 
    if (i >= -128 && i <= 127) { // must cache 
      return IntegerCache.cache[i + offset]; //这个主意下,Cache 缓存了-128~127的值
    } 
    return new Integer(i); 
  } 

 

   可以看出,这个值在-128到127之间,会将其cached(缓存)起来,如果多次使用的话,会节省内存和改善性能;如果不在这个范围之内,则生成一个新的Integer Object instance,这样如果进行“==”时,由于是比较两个不同的Object references,故结果是false。事实上,这个特性从JDK 1.3就存在了(以前的我不清楚) 。

    确切的说,上面出现的问题实质并不是Autoboxing和Auto-Unboxing,应该是Integer类的valueOf(int i)方法,只是Autoboxing和Auto-Unboxing将这个问题掩盖了。 

    把Integer 换成 int 则不会出现上述情况,结果都是equal。

 

分享到:
评论

相关推荐

    java设计模式【之】享元模式【源码】【场景:多缓存可选模式】

    * 内部状态:属性值由类生成时确定,不会改变 * 外部状态:属性值由参数决定,依赖传递值 * * 实现思路 * 多个位置的操作,需要相同的一些对象,此时将相同的一些对象封装进一个工厂内,创建后持久化到内存中 ...

    cyc学习笔记.pdf

    该缓存池由源码Integer.class中的IntegerCache这个私有静态内部类定义。该缓存池与jvm关系是:缓存池创建缓存数据,jvm会在常量池中直接找到该值引用。不用创建新的对象。还可以在jvm中设置缓存池hi最大值。

    【05-面向对象(下)】

    在外部类内部使用内部类-不要在外部类的静态成员中使用非静态内部类,因为静态成员不能访问非静态成 员。 • 2.在外部类以外使用非静态内部类。  –private 修饰的内部类只能在外部类内部使用。  –在外部...

    litecache:nodeJs 本地缓存

    精简缓存同步 NodeJS 内部缓存。 一个纯同步的轻量级缓存模块,具有常量时间set 、 get和del方法,其工作方式类似于字典映射。 缓存支持 ttl 删除过期值。 过期的 keyValue 对仅在get或del被修剪。 节点事件循环中...

    编译原理——词法分析代码

    对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组 id 中,将常数变为二进制形式存入数组中 ci 中,并记录其在表中的...

    Java面试题-基础和集合.docx

    其中,讨论了Java为什么不支持多继承、==和equals的区别、方法重载的条件、String为何设计成不可变、包装类的应用场景、Integer的高速缓存机制等多个方面。 通过面试题的逐一解答,读者可以了解到Java语言的一些...

    常用类

    8种基本类型所对应的对象类型,可以直接将基本类型的变量表示为一个对象,在执行变量类型的相互转换时,我们会大量使用这些包装类。 包装类有什么用? 1、支持null字面值,可以表示空值。 2、支持缓存,提高复用效率...

    java面试宝典

    156、在jsp:useBean语法中使用beanName有何好处? 37 157、当我使用时,在浏览器的地址栏没有改变? 37 158、如何转换JSP 0.9版本的文件到JSP1.1? 37 160、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么...

    千方百计笔试题大全

    156、在jsp:useBean语法中使用beanName有何好处? 37 157、当我使用时,在浏览器的地址栏没有改变? 37 158、如何转换JSP 0.9版本的文件到JSP1.1? 37 160、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么...

    android连接SQLite数据库源代码

    android内部有缓存可关闭也不关闭也行,查询rawQuery是方法 3.在分页有到Cursor(游标)取游标下一个值cursor.moveToNext(),用游标对象接数据 "select * from person limit ?,?" person不能加上where 关键字 4.在...

    grub4dos-V0.4.6a-2017-02-04更新

    例如:"七" 使用不同字型,将 .hex 文件中的 unicode 码 “4e03” 修改为 “0080”, 将菜单中的 "七" 修改为 “\X0080”。 2016-03-23(yaya) 增强 echo 函数功能。 例如:echo -e \x18 显示 UTF-8 字符 0x...

    Java面试宝典2010版

    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 2、Java有没有goto? 3、说说&和&&的区别。 4、在JAVA中如何跳出当前的多重嵌套循环? 5、switch语句能否作用在byte上,能否作用在long上...

    java面试题

    以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。 107 84.4. 现在输入n个数字,以逗号”,”分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset 108 84.5. 金额...

    最新Java面试宝典pdf版

    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...

    Java面试笔试资料大全

    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...

    Java面试宝典2012版

    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用...

    Oracle9i的init.ora参数中文说明

    说明: 在 SQL 语句中, 应避免使用繁琐的 NLS_SORT 进程。正常情况下, WHERE 子句中进行的比较是二进制的, 但语言比较则需要 NLSSORT 函数。可以使用 NLS_COMP 指定必须根据NLS_SORT 会话参数进行语言比较。 值范围:...

    Java面试宝典2012新版

    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...

    Java面试宝典-经典

    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...

Global site tag (gtag.js) - Google Analytics