Java--Integer的常量缓存池(默认-128~127数值范围)
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数值范围)相关推荐
- 【java】java Integer 缓存 一定是 -128~127 吗
1.概述 我们都知道 java Integer是有缓存的,缓存范围是 -128~127.但是这个值是一定的吗? 不一定.看源码.缓存大小居然可以改变 /*** Cache to support the ...
- Java 数据类型缓存池
package com.study.DataType;import org.junit.Test;/*** @Description 常量缓冲池* @Classname IntegerDemo* @D ...
- JAVA包装类型缓存池详解
前言:我们知道,缓存一些常用的数据能提高程序的运行效率,而在Java中,Java给一些基本类型提供了一个缓存池,缓存池中已经提前存进去了一些元素,提高数据的读取速度.在此之前,先了解一下Java的自动 ...
- Java数据类型缓存池
常量缓存池 package com.study.DataType;import org.junit.Test;/*** @Description 常量缓冲池* @Date 2021/9/5 10:56 ...
- Java Integer于Int 进行==双等于的内存比较时的一些问题说明
转自: https://blog.csdn.net/xingkongdeasi/article/details/79618421 部分有所修改: 前言: 越是简单的东西,我们往往越是没有去把它明白,但 ...
- byte的范围为何是-128~127,而不是-127~128?
一.计算机该怎么做减法? 比如2-1=1,1-1=0.由于种种原因(精力有限,暂不深究),加法电路难度和成本已经很高了, 当时的条件下,再去设计一个减法电路,费力又费钱,前辈们想用加法电路来 ...
- Java Integer 常量池
Integer类 Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的字段. 此外,该类提供了多个方法,能在 int 类型和 Stri ...
- Java 中 Integer 源码学习之缓存池了解
Java 中 Integer 源码学习之缓存池了解 面试题 new Integer(123) 与 Integer.valueOf(123) 的区别? new Integer(123) 每次都会新建一个 ...
- java jdk缓存-128~127的Long与Integer
先推断下以下代码的输出结果 Qa:---------------------------------------------- Long a = Long.valueOf(127); ...
最新文章
- 为什么数据线easy糟糕
- android自定义尺子收集demo
- 深度学习的五个能力级别
- 开灯变形问题(枚举法)
- C++中cin、cin.get()、cin.getline()、getline()等函数的用法
- snippet,让你编码效率翻倍
- Archsummit 2019重磅分享|闲鱼Flutter&FaaS云端一体化架构
- 「钓鱼攻击」免杀钓鱼上线捆绑利器
- Android应用开发的一些思考
- mysql正则表达式教学视频教程_MySQL正则表达式入门教程
- amd linux raid,请问AMD RAID驱动怎么用
- java毕业生设计web人力资源管理系统计算机源码+系统+mysql+调试部署+lw
- Codeforces300D Painting Square
- 第一章---计算机系统概论
- 转行做程序员,你后悔了吗
- 永恒之蓝-永恒之蓝漏洞(linux)
- web项目部署服务器上线
- oracle 联通 offer,29岁社招拿到中国联通offer,该不该去?
- 2017 android平板,苹果2017款iPad评测:史上性价比最高的体面iPad平板
- 很久没上来写点东西了,今天把N年前的代码看了一遍。随手写了点寄托哀思--多播委托...
热门文章
- 利用percona-toolkit 工具来检测mysql 主从数据库同步以及实现同步
- C#设计模式之代理模式(一)
- Booth编码以及运算实例
- 大连海洋计算机专业校址,大连海洋大学有几个校区,哪个校区最好及各校区介绍...
- 计算机与数学交融的教学设计,信息技术与小学数学学科的整合 小学数学教案...
- wingide5-forlinux cracked
- 幼儿园手工之自制时钟_幼儿园手工时钟玩教具制作图片
- 通过命令行,对ES进行操作
- 基于JAVA的洗衣店订单管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
- 手机屏幕投到Windows系统