Java 自动拆箱 装箱 包装类的缓存问题--结合源码分析
都0202 了 java 1.8 已经是主流
自动装箱 、拆箱已经很普遍使用了,那么有时候是不是会遇到坑呢?
我们先来看一段代码:
public class TestWraperClass {
public static void main(String[] args) {
Integer a = 200;
Integer b = 200;
Integer c = 123;
Integer d = 123;
System.out.println(a == b);
System.out.println(c == d);
}
}
运行结果:

代码中 a==b 结果为false 容易理解,毕竟是两个不同对象;
那么 c == d 为什么结果会是 true 呢?
其实在程序编译时,编辑器会给我们的代码加上 Integer.valueOf(int i)。
即上面的代码相当于:
Integer a = Integer.valueOf(200);
Integer b = Integer.valueOf(200);
Integer c = Integer.valueOf(123);
Integer d = Integer.valueOf(123);
我们可以按住CTRL键鼠标点击valueOf 查看JDK源码有这么一段代码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
也就是说,当给 Integer.valueOf(int i) 出入的参数在某个范围内是,会直接从一个数组中取值
我可以继续按住CTRL键鼠标点击 cache 进入 IntegerCache 类,我们可以看到源码如下:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int 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_VALUE
h = 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.cache[i + (-IntegerCache.low)] 其实就是一个 从-128 到 127 的 静态初始化 Integer 数组 ,当我们调用时,已经存在java 虚拟机的堆中了,不需要重新创建。
那么回到最开始的代码:
当我们创Integer 对象的值在[-127, 128] 范围时,其实取的都是 cache[] 数组的同一个对象。
至此,已经可以很好结算 开始代码的运行结果了。
Java 自动拆箱 装箱 包装类的缓存问题--结合源码分析的更多相关文章
- 关于Java自动拆箱装箱中的缓存问题
package cn.zhang.test; /** * 测试自动装箱拆箱 * 自动装箱:基本类型自动转为包装类对象 * 自动拆箱:包装类对象自动转化为基本数据类型 * * * /*缓存问题*/ /* ...
- Java 从Character和char的区别来学习自动拆箱装箱
本文结构 1.Character和char 的区别: 2.自动拆箱装箱 1.Character和char 的区别: Character是类,char基本数据类型. 在java中有三个类负责对字符的操作 ...
- Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析
Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析 Volley之所以高效好用,一个在于请求重试策略,一个就在于请求结果缓存. 通过上一篇文章http://www.cnblogs.com ...
- Java中的自动拆箱装箱(Autoboxing&Unboxing)
一.基本类型打包器 1.基本类型:long.int.double.float.boolean 2.类类型:Long.Integer.Double.Float.Boolean 区别:基本类型效率更高,类 ...
- java 自动拆箱 自动装箱
自动装箱的定义就是 基本数据类型赋值给包装类型, 拆箱则相反. Integer integer = 122; // 自动装箱 int num = integer; //自动拆箱 想看一下源码是怎么 ...
- 享元模式(FlyWeight Pattern)及其在java自动拆箱、自动装箱中的运用
本文主要从三个方面着手,第一:简要介绍享元模式.第二:享元模式在基本类型封装类中的运用以Integer为例进行阐述.第三:根据第一.第二的介绍,进而推出java是如何实现自动拆箱与装箱的. 第一:简要 ...
- JAVA高级特性--自动拆箱-装箱,枚举类型
基本数据类型转换为引用类型对象 一个自动装箱的例子 Integer i=10; 相当于 Integer i=new Integer(10); 一个自动拆箱的例子 Integer m=10; int n ...
- JavaWeb_静态导入、自动拆箱/装箱
静态导入用于简化程序对类静态属性和方法的调用. 语法 import static 包名.类名.静态属性|静态方法|* 例如 import static java.lang.System.out imp ...
- java 自动拆箱
Integer a0 = ; Integer a1 = ; Integer b0 = ; Integer b1 = ; ; System.out.println(a0 == a1); >> ...
随机推荐
- 将java中Map对象转为有相同属性的类对象(json作为中间转换)
java中Map对象转为有相同属性的类对象(json作为中间转换) 准备好json转换工具类 public class JsonUtil { private static ObjectMapper o ...
- Salesforce LWC学习(十五) Async 以及 Picklist 公用方法的实现
本篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) https://developer.salesfo ...
- opnet
一.修改默认的文件管理 1.以管理员身份运行 opnet14.5 2. 3.初始默认是c盘下的op_madels 4.修改你默认的文件夹 二. 1.创建一个空场景 包含Manet模型 2. 出错 二. ...
- 360网络安全学习笔记——SQLmap
SQLmap简介 SQLmap是一个开源的自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞. SQL注入模式 1.基于布尔的盲注 2.基于时间的盲注 3.基于报错注入 ...
- 查看手机wifi密码
方法一 手机共享wifi,获得二维码,之后解码获得密码. 二维码解吗工具: https://jiema.wwei.cn/ 方法二 手机扫描wifi共享的二维码后,会有提示信息,其中会显示出密码.
- jQuerry点击按钮回到顶部功能
简单实现点击按钮回到顶部功能
- CF632(div.2)C. Eugene and an array
https://codeforces.ml/contest/1333/problem/C 大概题意是规定和为0的数组为不合格数组,询问给定数组中共有多少个合格子数组. 解题 子数组的数量 一个长度为 ...
- Windows&linux使用集成环境搭建 web 服务器
文章更新于:2020-02-17 按照惯例,需要的文件附上链接放在文首 文件名:phpStudy_64.7z 文件大小:78.3 M 下载链接https://www.lanzous.com/i9c6l ...
- 100 Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
- 34.1 字符流-- FileRead FileWrite
一次读取一个字符 FileReader fr = new FileReader("aa.txt"); // System.out.println(fr.read()); // Sy ...