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源码分析的更多相关文章

  1. 设计模式(十二)——享元模式(Integer缓冲池源码分析)

    1 展示网站项目需求 小型的外包项目,给客户 A 做一个产品展示网站,客户 A 的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求都有些不同: 1) 有客户要求以新闻的形式发布 2) 有客户人要 ...

  2. Integer包装类源码分析

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 今天上班的途中在手机里看到几道关于Integer拆装箱的小题目,正好有点时间翻看了一下Integer类的源码,加上自己的一点思考,决定写点 ...

  3. Integer面试连环炮以及源码分析

    场景:   昨天有位朋友去面试,我问他面试问了哪些问题,其中问了Integer相关的问题,以下就是面试官问的问题,还有一些是我对此做了扩展. 问:两个new Integer 128相等吗? 答:不.因 ...

  4. Integer面试连环炮以及源码分析(转)

    场景:   昨天有位朋友去面试,我问他面试问了哪些问题,其中问了Integer相关的问题,以下就是面试官问的问题,还有一些是我对此做了扩展. 问:两个new Integer 128相等吗? 答:不.因 ...

  5. JDK源码分析-Integer

    Integer是平时开发中最常用的类之一,但是如果没有研究过源码很多特性和坑可能就不知道,下面深入源码来分析一下Integer的设计和实现. Integer: 继承结构: -java.lang.Obj ...

  6. MyCat源码分析系列之——BufferPool与缓存机制

    更多MyCat源码分析,请戳MyCat源码分析系列 BufferPool MyCat的缓冲区采用的是java.nio.ByteBuffer,由BufferPool类统一管理,相关的设置在SystemC ...

  7. MyCat源码分析系列之——配置信息和启动流程

    更多MyCat源码分析,请戳MyCat源码分析系列 MyCat配置信息 除了一些默认的配置参数,大多数的MyCat配置信息是通过读取若干.xml/.properties文件获取的,主要包括: 1)se ...

  8. MyBatis源码分析-SQL语句执行的完整流程

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

  9. [源码]String StringBuffer StringBudlider(2)StringBuffer StringBuilder源码分析

      纵骑横飞 章仕烜   昨天比较忙 今天把StringBuffer StringBulider的源码分析 献上   在讲 StringBuffer StringBuilder 之前 ,我们先看一下 ...

随机推荐

  1. day6 python while,for 循环控制

    1.1双向循环控制流程 i = 0 while i > 10: #外层循环 j = 10 while j < 0: #内层循环 j -= 1 i += 1 1.1.1 双向循环练习---- ...

  2. Java中多线程的使用(超级超级详细)线程安全原理解析 4

    Java中多线程的使用(超级超级详细)线程安全 4 什么是线程安全? 有多个线程在同时运行,这些线程可能会运行相同的代码,程序运行的每次结果和单线程运行的结果是一样的,而且其他变量的值也和预期的值一样 ...

  3. js中实现继承的方法

    目录 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承 借用构造函数 这种技术的基本思想很简单,就是在子类型构造函数的内部调用超类型的构造函数.另外,函数只不过是在特定环境中执行代码的对 ...

  4. corosync+pacemaker高可用集群

    高可用集群,是指以减少服务中断(如因服务器宕机等引起的服务中断)时间为目的的服务器集群技术.简单的说,集群就是一组计算机,它们作为一个整体向用户提供一组网络资源.这些单个的计算机系统就是集群的节点. ...

  5. vscode 无法自动补全第三方库

    点击Settings 找到“Extentions”下的“Python”,点击“Auto Completes: Extra Paths”的“Edit in settings.json”,如下图: 在se ...

  6. C# POST请求中raw 参数的传递

    public static string PostmanPost() { var client = new RestClient("http://119.3.248.64:3000" ...

  7. netcore RabbitMQ入门--win10开发环境

    安装 1.进入rabbitMQ官网下载安装包 2.点击安装包安装的时候会提示需要先装erlang 点击是会自动跳转到erlang的下载界面如果没有跳转可以直接点击这里下载,根据系统选择下载包 下载完之 ...

  8. time strptime()方法 时间操作

    Python time strptime()方法 时间操作   描述 Python time strptime() 函数根据指定的格式把一个时间字符串解析为时间元组. 语法 strptime()方法语 ...

  9. 感性认识JWT

    常见的认证机制 今天我么聊一聊JWT. 关于JWT,相信很多人都已经看过用过,他是基于json数据结构的认证规范,简单的说就是验证用户登没登陆的玩意.这时候你可能回想,哎哟,不是又那个session么 ...

  10. CentOS7.3 ffmpeg安装

    ffmpeg安装笔记 ======================== 一.安装依赖 yum -y install yum-utils yum-config-manager --add-repo ht ...