千家信息网

由自动装箱和拆箱引发我看Integer源码

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,背景和问题在看别人整理的资料时,看到如下一段代码:package com.sitech.test;/** * 自动装箱和拆箱 jdk1.6 * @author liaowp * */public cl
千家信息网最后更新 2025年02月01日由自动装箱和拆箱引发我看Integer源码

背景和问题

  在看别人整理的资料时,看到如下一段代码:

package com.sitech.test;/**
* 自动装箱和拆箱 jdk1.6
* @author liaowp
* */public class TestInteger { public static void main(String[] args) {
Integer i1 = 80, i2 = 80, i3 = 999, i4 = 999;
System.out.println(i1 == i2);//true
System.out.println(i3 == i4);//false }
}

  如果没有看过源码的同学肯定觉的答案要么是2个true要么是2个false。我刚看到这一段代码的时候也觉的是2个true,感觉自己100%确定,不过真正运行之后才发现傻眼了,一个true一个false,这是Bug吧。其实LZ以前看过一部分Integer源码了,但是现在想想好像看的不认真,尴尬了。于是被这个问题触发了LZ要认真看一次Integer源码了(我要认真了,哈哈)。

  我们还是回到上面那个问题吧,先把问题解决了在吹nb。我们可以看到上面的代码4个变量都是Integer的引用,所以输出的==运算比较的不是Integer值而是Integer引用。装箱的本质是什么呢?当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,我们看一看valueOf方法就知道为什么会有这样的结果了。

    /**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5 */
public static Integer valueOf(int i) {//是一个静态方法 IntegerCache是一个内部类 assert IntegerCache.high >= 127;//断言 参考http://lavasoft.blog.51cto.com/62575/43735/ if (i >= IntegerCache.low && i <= IntegerCache.high)//如果i大于对于IntegerCache.low()且i小于等于IntegerCache.high return IntegerCache.cache[i + (-IntegerCache.low)];//直接从缓存取出来 return new Integer(i);//新创建一个Integer对象
}

  从上面的代码中我们可以看出Integer维持了一个缓存系统,如果在缓存的范围内直接取出来就好了,雅思培训机构如果不在的就要创建新的Integer对象。但是具体缓存范围是什么的,我们在深入进去看看:

    /**
* 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 -XX:AutoBoxCacheMax= 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;//最小值是-128 static final int high;//最高 static final Integer cache[];//缓存数组 这三个都final,不可修改的 static {//静态代码块 静态代码块会比改造方法先执行 // high value may be configured by property
int h = 127;//默认的
String integerCacheHighPropValue =//定义一个String
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");//取得设置的值 if (integerCacheHighPropValue != null) {//如果设置了就用设置的值 int i = parseInt(integerCacheHighPropValue);//把String转换为int
i = Math.max(i, 127);//获得i和127的更大的一个,其实是不能小与默认的 // Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));//如果取的小的那个,不能超过Integer的最大值+low
}
high = h;//最大值为127

cache = new Integer[(high - low) + 1];//创建缓存数组大小 int j = low;//最小值 for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);//缓存初始化
} private IntegerCache() {}//私有构造
}

问题解决

Integer的缓存

  看完之后我相信基本都知道为啥一开始的那一段代码会这样了,我现在做一个小的总结,Integer里面有一个内部类IntegerCache,是用来做缓存优化性能的。默认缓存了-128到127中间的数字,据说这些使的比较频繁。其实java里面好多的类都有这样的优化。如果在-128-127之间的就直接拿缓存的,不在的就new一个Integer所以这也就解释了上面的那个问题了嘛


缓存 代码 问题 静态 方法 源码 对象 面的 装箱 最大 最小 数组 时候 最大值 范围 要么 最高 频繁 尴尬 三个 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 溺水绘画软件开发 国内的网络安全测评机构 ehs软件开发公司 疫情期间和平精英服务器崩溃 数据库基础到删库跑路书籍 自动化软件开发方向 数据库主键唯不唯一 工业网络技术毕业后干什么 技术架构应用和数据库分离 短视频app数据库表设计 软件开发进度计划编制软件 软件开发完如何产生收益 腾讯的数据库建在哪里 达梦数据库服务创建超时 官渡区智能化软件开发市场报价 电脑进入网络安全模式是哪个键 域控服务器频繁重启2016 成都网络安全工程师薪资 奉贤区通信网络安全防护标准 软件开发前期市场调研计划书 复制网站数据库文件路径 数据库中的查询需求是啥 服务器的几用户几核心是什么意思 java测试用例连数据库 揭阳软件开发招聘 会计系统由数据库和什么组成 人工智能大数据服务器 外文文献数据库wps 软件开发公司创意名字 路由器显示服务器错误怎么办
0