Integer.valueOf源码分析
1. 引言
在牛客网上看到这样一道题目,判断一下打印的结果
public static void main(String[] args){
Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1==i2);
Integer i3 = 100;
Integer i4 = 100;
System.out.println(i3==i4);
}
刚开始看到是,是这样来判断的:因为 Integer i1 = 128 这条语句,Integer 会启用自动装箱功能,调用 Integer.valueOf 方法返回一个 Integer 对象,因此这四个对象应该指向不同的地址,所以打印的结果是两个 false。但是在 eclipse 运行结果如下,为什么会这样呢?

2. 分析
首先想到的就是 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);
}
从中可以看出,valueOf 方法首先会判断 i 值是否在一个范围内,如果是的话,会从 IntegerCache 的 cache(其实是一个用 final static 修饰的数组) 中返回 Integer 对象,如果不在这个范围内,会创建一个新的 Integer 对象。那么就看一下这个范围是什么吧。跟到 IntegerCache 类内部,可以看到它定义的两个变量,low 为 -128,high 还未定义。
static final int low = -128;
static final int high;
通过 ctrl+F 查找 high 是什么时候创建的,发现是在一个静态代码块里面:
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
从中可以看出,high 的值是由 h 决定的,h 一般为 127。这说明,当 valueOf 传入的参数值在 -128~127 之间,这些数值都会存储在静态数组 cache 中。因此,在 valueOf 方法里,参数在 -128~127 之间,返回 Integer 对象的地址引用是一样的,对于题目也有了正确的解答。
3. 总结
刚开始学编程时,如果碰到问题时,都是把报错的信息赋值到百度或者谷歌上进行搜索,直接根据被人的踩坑经验,按照他们给的步骤来解决问题,现在我又发现了一种更高效的解决方案 -- 直接看源码,直接了解底层的实现,很快就可以解决问题了。所以,把自己的基础打牢,勿以浮沙筑高台!
Integer.valueOf源码分析的更多相关文章
- 设计模式(十二)——享元模式(Integer缓冲池源码分析)
1 展示网站项目需求 小型的外包项目,给客户 A 做一个产品展示网站,客户 A 的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求都有些不同: 1) 有客户要求以新闻的形式发布 2) 有客户人要 ...
- Integer包装类源码分析
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 今天上班的途中在手机里看到几道关于Integer拆装箱的小题目,正好有点时间翻看了一下Integer类的源码,加上自己的一点思考,决定写点 ...
- Integer面试连环炮以及源码分析
场景: 昨天有位朋友去面试,我问他面试问了哪些问题,其中问了Integer相关的问题,以下就是面试官问的问题,还有一些是我对此做了扩展. 问:两个new Integer 128相等吗? 答:不.因 ...
- Integer面试连环炮以及源码分析(转)
场景: 昨天有位朋友去面试,我问他面试问了哪些问题,其中问了Integer相关的问题,以下就是面试官问的问题,还有一些是我对此做了扩展. 问:两个new Integer 128相等吗? 答:不.因 ...
- JDK源码分析-Integer
Integer是平时开发中最常用的类之一,但是如果没有研究过源码很多特性和坑可能就不知道,下面深入源码来分析一下Integer的设计和实现. Integer: 继承结构: -java.lang.Obj ...
- MyCat源码分析系列之——BufferPool与缓存机制
更多MyCat源码分析,请戳MyCat源码分析系列 BufferPool MyCat的缓冲区采用的是java.nio.ByteBuffer,由BufferPool类统一管理,相关的设置在SystemC ...
- MyCat源码分析系列之——配置信息和启动流程
更多MyCat源码分析,请戳MyCat源码分析系列 MyCat配置信息 除了一些默认的配置参数,大多数的MyCat配置信息是通过读取若干.xml/.properties文件获取的,主要包括: 1)se ...
- MyBatis源码分析-SQL语句执行的完整流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- [源码]String StringBuffer StringBudlider(2)StringBuffer StringBuilder源码分析
纵骑横飞 章仕烜 昨天比较忙 今天把StringBuffer StringBulider的源码分析 献上 在讲 StringBuffer StringBuilder 之前 ,我们先看一下 ...
随机推荐
- GitHub 热点速览 Vol.28:有品位程序员的自我修养
作者:HelloGitHub-小鱼干 摘要:一个程序员除了技术好,还得品位高,有什么比一个高颜值的 GUI 更能体现你品味的呢?rocketredis 就是一个高颜值.简约的 Redis 管理界面,比 ...
- bzoj1680[Usaco2005 Mar]Yogurt factory*&&bzoj1740[Usaco2005 mar]Yogurt factory 奶酪工厂*
bzoj1680[Usaco2005 Mar]Yogurt factory bzoj1740[Usaco2005 mar]Yogurt factory 奶酪工厂 题意: n个月,每月有一个酸奶需求量( ...
- CSS3伪类 :empty
:empty 种类:伪类选择器 版本:CSS3.0 用法:匹配每个没有子元素(包含文本)的元素. 例子: <!DOCTYPE html> <html> <head> ...
- Mnist手写数字识别 Tensorflow
Mnist手写数字识别 Tensorflow 任务目标 了解mnist数据集 搭建和测试模型 编辑环境 操作系统:Win10 python版本:3.6 集成开发环境:pycharm tensorflo ...
- 题解 洛谷 P6349 【[PA2011]Kangaroos】
先考虑对题目进行转化,我们称两个区间有交集为这两个区间能匹配,每个询问就是在序列中最长能连续匹配的长度. 对序列中的一个区间\([l,r]\)和询问的一个区间\([L,R]\),若满足\(L \leq ...
- tomcat 认证爆破之custom iterator使用
众所周知,BurpSuite是渗透测试最基本的工具,也可是神器,该神器有非常之多的模块:反正,每次翻看大佬们使用其的骚操作感到惊叹,这次我用其爆破模块的迭代器模式来练练手[不喜勿喷] 借助vulhub ...
- 委托、匿名方法到lambda表达式
在项目中我们经常会接触lambda表达式,链式操作简洁明了.帮我们省了不少事.面对这么神奇的一个东西,是不是也应该了解了解它的本质呢. 今天我们通过一步一步的演变揭开lambda表达式的本质 一.委托 ...
- 常用核心数据库查询sql
一.查询账户信息 -- 查询数据量 /*{"xdb_comment":"1","table":"mb_tran_hist" ...
- 关于SignalR 进行双向多步对话
关于ASP.NET SignalR 解释百度百科是这样说的: ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 ...
- Java基础加强笔记——测试、反射、注解
目录 1. Junit单元测试 2. 反射 3. 注解 Junit单元测试: 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具 ...