Integer a=Integer.valueOf(100);
Integer b=Integer.valueOf(100);
System.out.println(a==b);
Double d1=Double.valueOf(100);
Double d2=Double.valueOf(100);
System.out.println(d1==d2); 
 
为什么包装类 Ingeter两个值就相等 Double的就不相等了呢

在给Integer赋值时,实际上是自动装箱的过程,也就是调用了Integer.valueOf(int)方法,当这个值大于等于-128并且小于等于127时使用了常量池,所以前两个地址是相等的,但是后两个超过了127,故不使用常量池。

也就是说
Integer -128~127实际上你可以看成是整形int,所以第一个类的输出结果应该是==
Interger 128以上的数值就不能看成int了,他是对象,两个值相同的不同的对象如果用==判断肯定是不等的,可以用equals判断。

 Java的8种基本类型(Byte, Short, Integer, Long, Character, Boolean, Float, Double), 除Float和Double以外, 其它六种都实现了常量池, 但是它们只在大于等于-128并且小于等于127时才使用常量池。 

Java包装类常量池详解

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); 
             Integer i7 = 140; 
             Integer i8 = 140;
            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("i7=i8\t" + (i7 == i8);
            System.out.println();         
        } 
    }

i1=i2 true
i1=i2+i3 true
i4=i5 false
i4=i5+i6 true

i7=i8 false

Java为了提高性能提供了和String类一样的对象池机制,当然Java的八种基本类型的包装类(Packaging Type)也有对象池机制。

Integer i1=40;Java在编译的时候会执行将代码封装成Integer i1=Integer.valueOf(40);通过查看Source Code发现:

Integer.valueOf()中有个内部类IntegerCache(类似于一个常量数组,也叫对象池),它维护了一个Integer数组cache,长度为(128+127+1)=256,Integer类中还有一个Static Block(静态块)。

从这个静态块可以看出,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=i2false i1=i2+i3true i4=i5false i4=i5+i6true

这是因为Integer i1=400,Integer i2=400他们的值已经超出了常量池的范围,JVM会对i1和i2各自创建新的对象(即Integer i1=new Integer(400)),所以他们不是同一个引用。

Java包装类的常量池的更多相关文章

  1. JAVA String介绍、常量池及String、StringBuilder和StringBuffer得区别. 以及8种基本类型的包装类和常量池得简单介绍

    一.概述 String是代表字符串的类,本身是一个最终类,使用final修饰,不能被继承. 二.定义方式   方式一:直接赋值法 String str1 = "hello"; 方式 ...

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

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

  3. 【Java_基础】java中的常量池

    1.java常量池的介绍 java中的常量池,通常指的是运行时常量池,它是方法区的一部分,一个jvm实例只有一个运行常量池,各线程间共享该运行常量池. java常量池简介:java常量池中保存了一份在 ...

  4. Java中的常量池

    JVM中有: Class文件常量池.运行时常量池.全局字符串常量池.基本类型包装类对象 常量池 Class文件常量池: class文件是一组以字节为单位的二进制数据流,在java代码的编译期间,编写的 ...

  5. 第46节:Java当中的常量池

    Java当中的常量池 在Java虚拟机jvm中,内存分布为:虚拟机堆,程序计数器,本地方法栈,虚拟机栈,方法区. 程序计数器是jvm执行程序的流水线,是用来存放一些指令的,本地方法栈是jvm操作系统方 ...

  6. 讲一讲Java的字符串常量池,看完你的思路就清晰了

    前言 很多朋友Java的字符串常量池的概念困扰了很长一段时间,最近研究了一下jvm指令码,终于对它有了大概的了解. 在展示案例前,我们需要先搞清楚一个概念,众所周知,jvm的内存模型由程序计数器.虚拟 ...

  7. Java字面常量与常量池

    Java中的字面常量(区别于final创建的有名常量)通常会保存在常量池中,常量池可以理解为像堆一样的内存区域.但是常量池有一个特性就是,如果常量池中已存在该常量将不会再次为该常量开辟内存 还是看个程 ...

  8. Java堆/栈/常量池以及String的详细详解(转)------经典易懂系统

    一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...

  9. Java 运行时常量池

    运行时常量池是方法区的一部分.class中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放在方法区的运行时常量池 ...

随机推荐

  1. [TCO2013]LitPanels

    题意:一个$n\times m$的无色网格,你可以在其中选择两个$x\times y$的子矩形并在其中将其中任意的格子涂上颜色,问最终能得到多少种不同的网格 做这题会用到一个概念叫包围盒(boundi ...

  2. 【tarjan+缩点】POJ1236[IOI1996]-Network of Schools

    [题意] 见:http://blog.csdn.net/ascii991/article/details/7466278 [思路] 缩点+tarjan,思路也可以到上面的博客去看.(吐槽:这道题其实我 ...

  3. [转]java框架spring中的opensessioninview有什么作用

    在hibernate中使用load方法时,并未把数据真正获取时就关闭了session,当我们真正想获取数据时会迫使load加载数据,而此时 session已关闭,所以就会出现异常. 比较典型的是在MV ...

  4. [转]MySQL与Oracle 差异比较之一数据类型

    数据类型 Oracle    MySQL     1 NUMBER int / DECIMAL DECIMAL就是NUMBER(10,2)这样的结构INT就是是NUMBER(10),表示整型:MYSQ ...

  5. <摘录>简述configure、pkg-config、pkg_config_path三者的关系

    一.什么是configure 源码安装过程中大多会用到configure这个程序,一般的configure都是一个script,执行时可以传入必要参数告知配置项目. configure程序它会根据传入 ...

  6. 基于tiny4412的Linux内核移植(支持device tree)(一)

    作者信息 作者: 彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本 ...

  7. 基于指定文本的百度地图poi城市检索的使用(思路最重要)

    (转载请注明出处哦)具体的百度地图权限和apikey配置以及基础地图的配置不叙述,百度地图定位可以看这个链接的http://blog.csdn.net/heweigzf/article/details ...

  8. cas服务器源码阅读笔记,对标博客

    对标源码阅读博客:http://www.cnblogs.com/jiuzhongguo/category/375405.html 在CAS中很多地方使用了策略模式,那么根据什么方式来确定使用哪种策略呢 ...

  9. 新公司官网项目优化实践(Vue)

    入职后接手website-html和website-mobile项目,发现项目加载速度不太理想,于是结合自己之前的经验对项目做了优化.此篇文章主要记录这次优化详情. 原始项目:开发环境:website ...

  10. 虚拟机选择配置:解决tomcat内存溢出

    用于解决java.tomcat内存溢出:-server -XX:PermSize=128M -XX:MaxPermSize=256m