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 ...
随机推荐
- codeforces 624C Graph and String
C. Graph and String time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- 1137 - Expanding Rods
1137 - Expanding Rods PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Limit: 32 M ...
- mod4最优路径问题(转载)
原文链接:https://blog.csdn.net/ACdreamers/article/details/18501855 mod4最优路径问题 如下图: 从1到4找出一条路径,要求路径的总长度mo ...
- 一个简单的js时钟
演示地址 代码 <html> <head> <title> Nonove js clock 时钟 </title> <script type=&q ...
- Towards Deep Learning Models Resistant to Adversarial Attacks
目录 概 主要内容 Note Madry A, Makelov A, Schmidt L, et al. Towards Deep Learning Models Resistant to Adver ...
- JSP的数据从数据库中获取导入type=date的input标签中
jsp 页面最开始加上 <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> & ...
- 初识python: 斐波拉契数(生成器获取)
使用 生成器(yield) 获取斐波拉契数. 代码如下: def fun(n): a,b,c = 0,0,1 while a < n: yield b # b, c = c, b + c 以下 ...
- Pytest_fixture(9)
什么是fixture fixture是pytest特有的功能,使用装饰器 @pytest.fixture 标记的函数在其他函数中能被当作参数传入并被调用. fixture有明确的名字,在其他函数,模块 ...
- Pytest_跳过用例的执行(7)
pytest跳过用例执行的用法与unittest跳过用例大致相同. pytest跳过用例的方法如下: pytest.mark.skip(reason):无条件用例.reason是跳过原因,下同. py ...
- JMeter_请求参数
在做接口测试时,发送请求的参数有两种格式,一种是Parameters,一种是JSON 一.Jmeter传参 JMeter 传Parameters格式的参数 JMeter 传JSON格式的参数 二.区分 ...