JDK1.5之后,新增了自动拆、装箱功能,如以前创建一个Integer对象,需要 使用 “new”关键字

而现在Java中可以直接赋值如下:

Integer不是new出Integer对象,而是直接赋值,就是自动装箱过程。

Integer a = new Integer("100");//JDK1.5之后
Integer b = 100;
int x = b;

再来测试如下代码:

/*** JDK1.5之后,新增了自动拆、装箱功能* 缓存以支持 JLS 要求的 -128 和 127(含)之间值的自动装箱的对象标识语义。* 缓存在第一次使用时初始化。 缓存的大小可以由 -XX:AutoBoxCacheMax=<size> 选项控制。* 在VM初始化过程中,java.lang.Integer.IntegerCache.high属性可能会被设置并保存在sun.misc.VM类的私有系统属性中** 1、IntegerCache 缓存范围为 -128~127(默认范围)* 2、大小可由 -XX:AutoBoxCacheMax调整*/
public class IntegerTest {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);Integer i5 = -150;Integer i6 = -150;System.out.println(i5 == i6);Integer i7 = 130;Integer i8 = 130;System.out.println(i7 == i8);Integer i9 = new Integer("127");Integer i10 = new Integer("127");System.out.println(i9 == i10);}
}

输出结果如下:

true
true
false
false
false

一、Integer缓存池 IntegerCache

我们可以看下 Integer.java 类 源码:

/*** Cache to support the object identity semantics of autoboxing for values between* -128 and 127 (inclusive) as required by JLS.** The cache is initialized on first usage.  The size of the cache* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.* During VM initialization, java.lang.Integer.IntegerCache.high property* may be set and saved in the private system properties in the* sun.misc.VM class.*/private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h = 127;String integerCacheHighPropValue =sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {try {int i = parseInt(integerCacheHighPropValue);i = Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {// If the property cannot be parsed into an int, ignore it.}}high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++)cache[k] = new Integer(j++);// range [-128, 127] must be interned (JLS7 5.1.7)assert IntegerCache.high >= 127;}private IntegerCache() {}}

IntegerCache 方法上注释大概意思

缓存以支持 JLS 要求的 -128 和 127(含)之间值的自动装箱的对象标识语义。
缓存在第一次使用时初始化。 缓存的大小可以由 -XX:AutoBoxCacheMax=<size> 选项控制。
在VM初始化过程中,java.lang.Integer.IntegerCache.high属性可能会被设置并保存在sun.misc.VM类的私有系统属性中。

由此得到2个重点关键字

1、IntegerCache 缓存范围为 -128~127(默认范围)

2、大小可由 -XX:AutoBoxCacheMax 调整

可以得到解释缓存生成的范围是-128~127,参数可以启动之前配置JVM参数AutoBoxCacheMax进行修改

Integer类中存在一个缓冲范围,有一个规范叫JSL(Java Language Specification,java语言规范)对Integer的缓冲做了约束,规定其范围为:(-128-127)之间

这的IntegerCache有一个静态的Integer数组,在类加载时就将 -128 到 127 的Integer对象创建了,并保存在cache数组中,一旦程序调用valueOf 方法,如果 变量i 的值是在-128 到 127 之间就直接在cache缓存数组中去取Integer对象。

如果超出了范围,会从堆区new一个Integer对象来存放值

再看其它的包装器:

Boolean:(全部缓存)
Byte:(全部缓存)

Character(<= 127缓存)
Short(-128 — 127缓存)
Long(-128 — 127缓存)

Float(没有缓存)
Doulbe(没有缓存)

这时,我们看下上述代码的内存图

1、Java中,在-128~127的Integer值并且以

Integer x = value;

的方式赋值的Integer值在进行==和equals比较时,都会返回true,因为Java里面对处在在-128~127之间的Integer值,用的是原生数据类型int,会在整数型常量内存池里,也就是说这之间的Integer值进行==比较时只是进行int原生数据类型的数值比较,而超出-128~127的范围,进行== 比较时是进行地址及数值比较

2、如果通过

Integer x = new Integer("127");

方式创建,还是和以前创建对象引用一样,在堆区中创建一个对象,然后将栈中引用指向这个对象,因此 i7 和 i8两个引用内存地址不同

:Java中的Integer数值范围并不是-128到127。Java中的int占用4个字节,4*8=32位,去除一个符号位,实际表示数据大小的有32-1位;而是说有一个整数常量缓存池供Integer自动装箱时使用,提高效率。

二、IntegerCache范围修改

1、我们在JVM运行参数上加上 -XX:AutoBoxCacheMax=200

IDEA中,在界面位置依次选择

Run --> Eidt Configurations --> Modify options --> Add VM options

VM options 添加 -XX:AutoBoxCacheMax=200参数

添加之后就能在界面位置看到了,可以添加运行参数

Apply后 运行代码 查看效果

public static void main(String[] args) {Integer a = 127;Integer b = 127;System.out.println(a == b);Integer c = 128;Integer d = 128;System.out.println(c == d);Integer e = 200;Integer f = 200;System.out.println(e == f);Integer g = 201;Integer h = 201;System.out.println( g == h);}

输出结果如下:

true
true
true
false

200时取自IntegerCache, 201则是不同指针的new Integer了。证明配置生效

2、我们在JVM运行参数上加上 -XX:AutoBoxCacheMax=120

public static void main(String[] args) {Integer a = 127;Integer b = 127;System.out.println(a == b);Integer c = 128;Integer d = 128;System.out.println(c == d);Integer e = 100;Integer f = 100;System.out.println(e == f);}

输出如下:

true
false
true

此时缓存池的值high是120,a、b = 127时 127应该是new的 a == b 应该是false

难道配置没生效,其实还是127?

其实不是我们设置的没生效,通过打印high的值,我们发现配置确实是生效了的,但没生效的原因是源码中做了判断。贴一段IntegerCache中为缓存池最大值赋值的方法

vm参数AutoBoxCacheMax的值与127做判断,取最大值,也就是说,如果我们设置的AutoBoxCacheMax参数比127小,则不会生效

结论:

-XX:AutoBoxCacheMax设置可以修改缓存池的最大范围,但需要大于127才能生效,小于等于127时,依然取的是默认值127

Java--Integer的常量缓存池(默认-128~127数值范围)相关推荐

  1. 【java】java Integer 缓存 一定是 -128~127 吗

    1.概述 我们都知道 java Integer是有缓存的,缓存范围是 -128~127.但是这个值是一定的吗? 不一定.看源码.缓存大小居然可以改变 /*** Cache to support the ...

  2. Java 数据类型缓存池

    package com.study.DataType;import org.junit.Test;/*** @Description 常量缓冲池* @Classname IntegerDemo* @D ...

  3. JAVA包装类型缓存池详解

    前言:我们知道,缓存一些常用的数据能提高程序的运行效率,而在Java中,Java给一些基本类型提供了一个缓存池,缓存池中已经提前存进去了一些元素,提高数据的读取速度.在此之前,先了解一下Java的自动 ...

  4. Java数据类型缓存池

    常量缓存池 package com.study.DataType;import org.junit.Test;/*** @Description 常量缓冲池* @Date 2021/9/5 10:56 ...

  5. Java Integer于Int 进行==双等于的内存比较时的一些问题说明

    转自: https://blog.csdn.net/xingkongdeasi/article/details/79618421 部分有所修改: 前言: 越是简单的东西,我们往往越是没有去把它明白,但 ...

  6. byte的范围为何是-128~127,而不是-127~128?

     一.计算机该怎么做减法?     比如2-1=1,1-1=0.由于种种原因(精力有限,暂不深究),加法电路难度和成本已经很高了, 当时的条件下,再去设计一个减法电路,费力又费钱,前辈们想用加法电路来 ...

  7. Java Integer 常量池

    Integer类 Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的字段.     此外,该类提供了多个方法,能在 int 类型和 Stri ...

  8. Java 中 Integer 源码学习之缓存池了解

    Java 中 Integer 源码学习之缓存池了解 面试题 new Integer(123) 与 Integer.valueOf(123) 的区别? new Integer(123) 每次都会新建一个 ...

  9. java jdk缓存-128~127的Long与Integer

    先推断下以下代码的输出结果 Qa:---------------------------------------------- Long a = Long.valueOf(127);          ...

最新文章

  1. 为什么数据线easy糟糕
  2. android自定义尺子收集demo
  3. 深度学习的五个能力级别
  4. 开灯变形问题(枚举法)
  5. C++中cin、cin.get()、cin.getline()、getline()等函数的用法
  6. snippet,让你编码效率翻倍
  7. Archsummit 2019重磅分享|闲鱼Flutter&FaaS云端一体化架构
  8. 「钓鱼攻击」免杀钓鱼上线捆绑利器
  9. Android应用开发的一些思考
  10. mysql正则表达式教学视频教程_MySQL正则表达式入门教程
  11. amd linux raid,请问AMD RAID驱动怎么用
  12. java毕业生设计web人力资源管理系统计算机源码+系统+mysql+调试部署+lw
  13. Codeforces300D Painting Square
  14. 第一章---计算机系统概论
  15. 转行做程序员,你后悔了吗
  16. 永恒之蓝-永恒之蓝漏洞(linux)
  17. web项目部署服务器上线
  18. oracle 联通 offer,29岁社招拿到中国联通offer,该不该去?
  19. 2017 android平板,苹果2017款iPad评测:史上性价比最高的体面iPad平板
  20. 很久没上来写点东西了,今天把N年前的代码看了一遍。随手写了点寄托哀思--多播委托...

热门文章

  1. 利用percona-toolkit 工具来检测mysql 主从数据库同步以及实现同步
  2. C#设计模式之代理模式(一)
  3. Booth编码以及运算实例
  4. 大连海洋计算机专业校址,大连海洋大学有几个校区,哪个校区最好及各校区介绍...
  5. 计算机与数学交融的教学设计,信息技术与小学数学学科的整合 小学数学教案...
  6. wingide5-forlinux cracked
  7. 幼儿园手工之自制时钟_幼儿园手工时钟玩教具制作图片
  8. 通过命令行,对ES进行操作
  9. 基于JAVA的洗衣店订单管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  10. 手机屏幕投到Windows系统