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. 【后缀自动机】hihocoder1449 后缀自动机三·重复旋律6

    解题方法提示 小Hi:上次我们已经学习了后缀自动机了,今天我们再来解决一个用到后缀自动机的问题. 小Ho:好!那我们开始吧! 小Hi:现在我们要对K=1..length(S)求出所有长度为K的子串中出 ...

  2. Largest Smallest Cyclic Shift

    Largest Smallest Cyclic Shift 题目来源: Atcoder Code Festival 2017 Qual B Problem F 题目大意: 有\(X\)个字符'a',\ ...

  3. spring quartz 配置

    quartz简介 各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁定用户解锁任务.任务调度本身涉及到多线程 ...

  4. [NOIP2013 花匠] 新人解题报告

    本来按照老师的要求,我学OI的第一份解题报告应是在寒假完成的关于数据结构的基础题,但由于身体原因当时未能完成,那么就在省选赛前临时写几篇吧…… 题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿 ...

  5. c++中const使用详解

    const在c++中是一个关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的安全性和可靠性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些 ...

  6. 面试DB优化

    高频全表扫描 0.5 表大小超过200M,且SQL高频执行(15分钟内超过500次),PIR 3级,表大小超过高速缓存的1.5%,报PIR 2级. 禁止使用select * 0.5 禁止使用selec ...

  7. IIS整合tomcat

    IIS6.0+Tomcat7.0整合总结 (一)   为什么要把IIS.Tomcat整合到一起? 假如你遇到这种情况,你开发了一个javaweb项目要部署到服务器上,但是这个服务器上已经部署了asp. ...

  8. Add Two Numbers(from leetcode python 链表)

    给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -& ...

  9. Oracle 命令导入数据

    1.用命令进入sqlplus: sqlplus 用户名:/orcl 2.执行sql文件 sql>@D:/lanxi_his_data/V_JH_VISITINFO.sql

  10. stderr重定向

    在测试alljoyn时开启了内部日志,输出太多想重定向到文件中,使用如下命令: ./chat -s aaa >.txt 居然还是打印到屏幕上而不是输出到文件中. 查看alljoyn写日志的代码, ...