通过本质看现象:关于Integer受内部初始化赋值范围限制而出现的有趣现象

简介: Integer源码解析

这是数年前写的第一篇技术文章。

 

前几天我在逛论坛的时候,偶然看到有人讨论这样一个现象,定义四个Integer类型的变量,分别初始化赋值为a=100,b=100,c=1000,d=1000,然后用println分别打印输出a==b和c==d的boolean值。这时就会出现一个很有趣的现象,a==b会被判断为ture,而c==d被判断为false。我觉得这个问题有点意思,自己玩了一遍,运行截图如下:

image.png

     问题便来了,同样类型的数值,为何a==b是正确的,而c==d则被判断为错误。在我们现实生活中,人们总说要透过现象去看本质,但若能反过来通过本质来分析现象,我想,同样可以深入理解很多东西。就像你能读懂一个人,就会很容易理解这个人的所作所为。打一个比方,你要弄懂一个人为何要犯罪,首先得了解他做这件事的心理,这就是通过本质回过头去看现象。

     这道题,如果能通过本质来看现象,就会茅塞顿开。

     Integer的本质是什么,当然是它的源码咯。

   在我们定义Integer a=100时,编译器会转成Integer.valueOf(100),即内部实现是Integer  a= Integer.valueOf(100),而在Integer的源码里valueOf方法如下:

publicstaticIntegervalueOf(inti) {
if (i>=IntegerCache.low&&i<=IntegerCache.high)
returnIntegerCache.cache[i+ (-IntegerCache.low)];
returnnewInteger(i);
}

 


   通过Integer的内部代码,可以看到有一个范围,即IntegerCache.low和IntegerCache.high。通常情况两者默认初始化为IntegerCache.high=127,IntegerCache.low=-128,同时,Integer内部还有一个静态static代码块,它会在类被加载时被执行,该代码块如下:

static {
inth=127;
StringintegerCacheHighPropValue=sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue!=null) {
try {
inti=parseInt(integerCacheHighPropValue);
i=Math.max(i, 127);
h=Math.min(i, Integer.MAX_VALUE- (-low) -1);
                } catch( NumberFormatExceptionnfe) {
                }
            }
high=h;
cache=newInteger[(high-low) +1];
intj=low;
for(intk=0; k<cache.length; k++)
cache[k] =newInteger(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)assertIntegerCache.high>=127;
    }


在执行该静态代码块时,会新建一个数组cache,把-128到127的数字都放在这里面。再结合前面的valueOf方法,可以看出,如果赋值的参数在127个-128之间,就会直接从静态代码块的缓存中返回一个实际数,它们都属于同一个对象;如果超过这个范围,就会return new Integer(i),即返回一个新建且不同的对象值。

   分析完Integer的部分源码后,就可以知道前面问题为何会出现这样的现象了。当a,b赋值为100时,两者都在127~-128的范围间,在同一个缓冲中,属于同一个对象且数值相同,那样a==b即为true;而当c,d赋值为1000时,就超过了范围,就会创建新的对象,两个引用指向不同的对象,即使对象拥有相同的内容,用==比较结果依然是false,这样的话,c,d已不属于同一个对象了,自然就会为false。

 

目录
相关文章
|
缓存 数据安全/隐私保护 Kotlin
Kotlin 中的网络请求代理设置最佳实践
Kotlin 中的网络请求代理设置最佳实践
|
11月前
|
存储 算法 应用服务中间件
Tomcat如何配置JKS证书?
【10月更文挑战第2天】Tomcat如何配置JKS证书?
978 4
|
存储 机器学习/深度学习 并行计算
95% 的算法都是基于这 6 种算法思想 (详细介绍)
95% 的算法都是基于这 6 种算法思想 (详细介绍)
359 4
|
并行计算 Linux iOS开发
Julia 教程
Julia,一款高性能的开源编程语言,专为科学计算设计,具备动态高级语言特性,速度快,无需解释器。支持多种平台,包括macOS、Windows和Linux等。其特点是小核心、丰富的类型语法、高性能、并行计算优化、C函数直接调用、Unicode支持及元编程工具。常用于数值计算。首个Julia程序示例为打印&quot;Hello World!&quot;。参考链接:[Julia官网](https://julialang.org/)和[Julia中文手册](https://docs.juliacn.com/latest/)。
|
前端开发 JavaScript
前端 JS 经典:数字变化动画
前端 JS 经典:数字变化动画
270 0
|
存储 Java 关系型数据库
实时计算 Flink版操作报错合集之JVM Metaspace不回收并在任务取消后仍然持续增长直至耗尽,是什么导致的
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
247 0
|
消息中间件 分布式计算 Kafka
50道大数据精选面试题
50道大数据精选面试题
|
监控 Java 大数据
软件体系结构 - 垃圾收集器(2)Parallel GC
【4月更文挑战第22天】软件体系结构 - 垃圾收集器(2)Parallel GC
690 3
|
自然语言处理 Python
python实现分词器
python实现分词器
186 0