Integer缓冲区相关问题--valueOf()方法
今天在学习过程中了解到一个现象,代码如下:
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1==num2?true:false);
//***********************************************
Integer num3 = 200;
Integer num4 = 200;
System.out.println(num3==num4?true:false);
这串代码,上面比较的是100装箱后比较和200装箱后比较,但是结果比较奇怪:

一个是true一个是false
首先要明确两点:
- Integer是包装类而不是基本数据类型,类型相比是要复杂一些的
- 装箱过程在编译器内进行了默认的valueOf()操作
所以该比较是比较的类,并且比较的是通过装箱操作的包装类。
回到重点,那么为什么100之间和200之间的比较完全不同?这涉及到Integer缓冲区的问题,我们可以查询一下Integer内的valueOf()方法:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
解释一下这串代码,就是说装箱操作并不是简简单单就装进去就完事,其中需要判断该数i是不是满足 low <= i <= high
而缓冲区内:
int low = -128;
int high = 127;
而在这个范围,就把这个装箱后的结果取作cache数组内原有的某个结果,cache的数组区间为:
cache = new Integer[(high - low) + 1];//也就是256
譬如刚刚的例子中:
- 当num=100,此时判断在这个范围内,则将Integer(100)变成Integer cache[228],无论是地址还是内容都是cache[228],所以num1 == num2
- 当num=200,它就不在这个范围内了,那么根据函数,直接返回Integer(200),类的存储是在堆中存储的,num3,num4分别new了一个Integer,各自是不同的对象了,所以num3 !=num4
这里画一个图更容易理解,对象存储在堆中,基本类型变量存储在栈中,装箱经过从栈到堆的转换,这里创建两个100和两个200的变量进行装箱操作,示例如下:

所以结论:
当显式或者间接使用valuOf()方法时,若数值在Integer缓冲区范围内,则无论创造多少次对象都是取的缓冲区数组cache[]的原有对象,这些对象都是完全相同的;但如果不在缓冲区范围,无论创建多少次对象都是新创建的,即使内容一致也不是同一个对象。
欢迎各位提出见解
Integer缓冲区相关问题--valueOf()方法的更多相关文章
- 关于Integer类中parseInt()和valueOf()方法的区别以及int和String类性的转换.以及String类valueOf()方法
Integer类中的. 关于parseInt()方法的API文档. 返回的是int类型的 关于valueOf()方法的API文档 返回的是Integer类型的. 关于intValue()方法的API ...
- Integer.valueOf方法的源码解读
public class IntegerDemo { public static void main(String[] args) { Integer i01 = ; ; Integer i03 = ...
- js中toString和valueOf方法的区别
toString 方法 返回对象的字符串表示形式. 语法:objectname.toString([radix]) objectname 必需.要为其搜索字符串表示形式的对象. radix 可选.为将 ...
- JavaScript引用类型之Array数组的toString()和valueof()方法的区别
一.转换方法 1.在JavaScript中几乎所有对象都具有toLocaleString().toString和valueof()方法,因为,所有的对象都继承自Object,而前面所说的方法都是Obj ...
- java 中的valueOf方法和强转
case1:Object 对象转String 需要强调的是String.valueOf()方法,当参数为类型是object,且值时null的时候他的处理方式 public static String ...
- Integer的parseInt和valueOf的区别
先来看一下下面这段代码 String s = "1"; System.out.println(Integer.valueOf(s)); System.out.println(Int ...
- scanf()中清除输入缓冲区的几种方法归纳
应用场景:我们使用多个scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容,为了隔离这种 ...
- Android随笔之——Android时间、日期相关类和方法
今天要讲的是Android里关于时间.日期相关类和方法.在Android中,跟时间.日期有关的类主要有Time.Calendar.Date三个类.而与日期格式化输出有关的DateFormat和Simp ...
- JavaScript的toString()和valueof()方法
toString()方法: 函数:函数 (function(){}).toString(); //返回"function(){}" typeof((function(){}).to ...
随机推荐
- 【LeetCode】187. Repeated DNA Sequences 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/repeated ...
- JVM调参
今天看了下之前做的一个异步处理任务的服务,发现占用内存量比较大,达到2G,但我检查了代码,基本没有static对象.但这个服务有个特点,就是每次执行一个任务的时候,会从数据库中捞大量的数据做处理,因此 ...
- MyBatis 流式查询
流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果.流式查询的好处是能够降低内存使用. 流式查询的过程当中,数据库连接是保持打开状态的,因此要注意的是:执行一个 ...
- Categorical Reparameterization with Gumbel-Softmax
目录 概 主要内容 Gumbel distribution Jang E., Gu S. and Poole B. Categorical reparameterization with gumbel ...
- 跨域The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.解决方案
使用Ajax跨域请求资源,Nginx作为代理,出现:The 'Access-Control-Allow-Origin' header contains multiple values '*, *', ...
- 基于Spring MVC + Spring + MyBatis的【人事管理系统】
资源下载:https://download.csdn.net/download/weixin_44893902/33163160 一.语言和环境 实现语言:JAVA语言 环境要求:IDEA/Eclip ...
- Oracle的dbf文件迁移
1.背景说明 在Oracle数据库中插入了1.5亿条数据, 并且创建了主键索引, 又插入了1.5亿条数据到另外一张表, 导致数据库表空间暴涨到28G, 由于根目录下只有50G的空间, 数据库文件所在磁 ...
- xorm 条件查询时区的问题
问题描述:如果在查询的时候,直接传时间格式作为条件,时间会被驱动程序转为UTC格式,因此会有8个小时的误差. 解决方案1: 将查询时间转为字符串 db.where("time > ?& ...
- PHP DateTime类常用方法总结
实例化: $date = new DateTime(); $date = new DateTime('2018-01-01'); $date = new DateTime('tomorrow'); $ ...
- Jenkins_构建任务提示找不到命令的处理方法
问题现象 部署pytest环境后,在linux上能执行命令,但是使用jenkins构建就提示找不到命令. 问题分析 可能是...jenkins中执行时,默认使用的是linux中的jenkins用户权限 ...