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】358. Rearrange String k Distance Apart 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/rearrang ...
- 【LeetCode】479. Largest Palindrome Product 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- TensorFlow.NET机器学习入门【6】采用神经网络处理Fashion-MNIST
"如果一个算法在MNIST上不work,那么它就根本没法用:而如果它在MNIST上work,它在其他数据上也可能不work". -- 马克吐温 上一篇文章我们实现了一个MNIST手 ...
- CS5211替代兼容PS8625|DP转LVDS|CS5211设计方案详解
PS8625是一个DP显示端口 到LVDS转换器芯片,利用GPU和显示端口(DP) 或嵌入式显示端口(eDP) 输出和接受LVDS输入的显示面板.PS8625实现双通道DP输入,双链路LVDS输出.P ...
- 适配器模式(pthon)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # adapter_pattern.py # 适配器模式 class Adaptee: def reque ...
- gitlab修改(重置)root用户密码
gitlab修改(重置)root用户密码 1.使用root权限登录到服务器. 2.使用以下命令启动控制台: gitlab-rails console production 该命令有时候启动比较慢,需 ...
- Linux shell 脚本中使用 alias 定义的别名
https://www.cnblogs.com/chenjo/p/11145021.html 核心知识点: 用 shopt 开启和关闭 alias 扩展 交互模式下alias 扩展默认是开启的,脚本模 ...
- R语言基本数据对象之向量的主要运算
在R语言里操作和接触的所有东西都称作对象(object).对象有很多种类 可以包含各种类型的数据.R 语言里所有的东西都被称为对象,R语言中常见的数据类型有几下几种,分别是字符型 (character ...
- java mapreduce二次排序
原文链接: https://www.toutiao.com/i6765808056191156748/ 目的: 二次排序就是有下面的数据 a 3 a 1 a 100 c 1 b 2 如果只按照abc排 ...
- “老”的Flexbox和“新”的Flexbox
本文由大漠根据Chris Coyier的<"Old" Flexbox and "New" Flexbox>所译,整个译文带有我们自己的理解与思想,如 ...