一个Java question,求输出结果
 
public class IntegerTest {
public static void main(String[] args) {
objPoolTest();
} public static void objPoolTest() {
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0); System.out.println("i1=i2 \t" + (i1 == i2));
System.out.println("i1=i2+i3 \t" + (i1 == i2 + i3));
System.out.println("i4=i5 \t" + (i4 == i5));
System.out.println("i4=i5+i6 \t" + (i4 == i5 + i6)); System.out.println();
}
}
 

输出结果是

i1=i2 	true
i1=i2+i3 true
i4=i5 false
i4=i5+i6 true
看起来比较Easy的问题,但是Console输出的Result和我们所想的确恰恰相反,我们就疑惑了,这是为什么咧?
最后通过网上搜索得知Java为了提高性能提供了和String类一样的对象池机制,当然Java的八种基本类型的包装类(Packaging Type)也有对象池机制。

Integer i1=40;Java在编译的时候会执行将代码封装成Integer i1=Integer.valueOf(40);通过查看Source Code发现
   /**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> 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 <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
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);
}
Integer.valueOf()中有个内部类IntegerCache(类似于一个常量数组,也叫对象池),它维护了一个Integer数组cache,长度为(128+127+1)=256;Integer类中还有一个Static Block(静态块)
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
从这个静态块可以看出,Integer已经默认创建了数值【-128-127】的Integer缓存数据。所以使用Integer i1=40时,JVM会直接在该在对象池找到该值的引用。   也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的缓存池中查找有木有值为40的对象,如果有直接返回该对象的引用;如果没有,则使用New keyword创建一个对象,并返回该对象的引用地址。因为Java中【==】比较的是两个对象是否是同一个引用(即比较内存地址),i2和i2都是引用的同一个对象,So i1==i2结果为”true“;而使用new方式创建的i4=new Integer(40)、i5=new Integer(40),虽然他们的值相等,但是每次都会重新Create新的Integer对象,不会被放入到对象池中,所以他们不是同一个引用,输出false。

  对于i1==i2+i3、i4==i5+i6结果为True,是因为,Java的数学计算是在内存栈里操作的,Java会对i5、i6进行拆箱操作,其实比较的是基本类型(40=40+0),他们的值相同,因此结果为True。
     好了,我想说道这里大家应该都会对Integer对象池有了更进一步的了解了吧,我在诺诺的问一句如果把40改为400猜猜会输出什么?
 
i1=i2 	false
i1=i2+i3 true
i4=i5 false
i4=i5+i6 true
这是因为Integer i1=400,Integer i2=400他们的值已经超出了常量池的范围,JVM会对i1和i2各自创建新的对象(即Integer i1=new Integer(400)),所以他们不是同一个引用。
 
 
转载自:http://www.tuicool.com/articles/aqyaYnm

Java常量池详解之Integer缓存的更多相关文章

  1. 【转】Java常量池详解

    今天My partner问我一个让他头疼的Java question,求输出结果: /** * * @author DreamSea 2011-11-19 */ public class Intege ...

  2. Java常量池详解

    转自:http://www.cnblogs.com/iyangyuan/p/4631696.html jvm虚拟内存分布图: 程序计数器:JVM执行程序的流水线. 本地方法栈:JVM调用操作系统方法所 ...

  3. java中的String类常量池详解

    test1: package StringTest; public class test1 { /** * @param args */ public static void main(String[ ...

  4. 《Java虚拟机原理图解》 1.2.3、Class文件中的常量池详解(下)

    CONSTANT_Fieldref_info, CONSTANT_Name_Type_info) 一般而言,我们在定义类的过程中会定义一些 field 字段,然后会在这个类的其他地方(如方法中)使用到 ...

  5. Java线程池详解(二)

    一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉 ...

  6. 19、java内存分配 常量池详解

    在class文件中,“常量池”是最复杂也最值得关注的内容. Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如Stri ...

  7. java常量池詳解

    一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池在Clas ...

  8. 《Java虚拟机原理图解》 1.2.2、Class文件中的常量池详解(上)

    我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了class的文件结构,在class文件中的魔数.副版本号.主版本之后,紧接着就是常量池的数据区域了,如下 ...

  9. Java虚拟机原理图解-- 1.2.2、Class文件中的常量池详解(上)[转]

    NO1.常量池在class文件的什么位置? 我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了class的文件结构,在class文件中的魔数.副版本号.主 ...

随机推荐

  1. 20135208 JAVA第四次实验

    课程:Java程序与设计     班级:1352 姓名:贺邦 小组成员: 20135212池彬宁 20135208贺邦 学号:20135208 成绩:             指导教师:娄嘉鹏     ...

  2. ACM-ICPC 2018 沈阳赛区网络预赛

    Supreme Number 1000ms 131072K   A prime number (or a prime) is a natural number greater than 111 tha ...

  3. lintcode-488-快乐数

    488-快乐数 写一个算法来判断一个数是不是"快乐数". 一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为他每个位置上的数字的平方和,然后重复这个过程直到这个数变为 ...

  4. WebSphere Application Server诊断和调优

    近段时间,我们项目中用到的WebSphere应用服务器(WAS),但在客户的production环境下极不稳定,经常宕机.给客户造成非常不好的影响,同时,也给项目组很大压力.为此,我们花了近一个月时间 ...

  5. 通过js读取元素的样式

    /* * 通过元素.style.样式只能获取到内联样式的值,就是style写在元素里面的值,不能获取嵌入式和外联样式的值 * 所以如果要获取除内联样式后的值,就不能通过这个获取 * alert(box ...

  6. 转 Maven常用仓库地址以及手动添加jar包到仓库

    转自:http://blog.csdn.net/kqygww/article/details/12837783 共有的仓库 http://repository.sonatype.org/content ...

  7. 使用union all 遇到的问题(俩条sql语句行数的和 不等于union all 后的 行数的和 !);遗留问题 怎么找到 相差的呐俩条数据 ?

    create table buyer as SELECT b.id AS bankid FROM v_product_deal_main m, base_member b WHERE b.id = m ...

  8. ci上传图片

    o_upload.php <?php /** * Created by PhpStorm. * User: brady * Date: 2018/3/15 * Time: 14:10 */ cl ...

  9. vue.cli实现tab切换效果

    <template> <div class="cp-select">                     <div class="lef ...

  10. web端调百度地图页面

    在点击进入地图的入口(下面数据是vue渲染的数据) <a class="navigation" v-if="merchant.longitude && ...