Interger对象源码解析
今天研究了Interger的源码,看了源码后才知道根本,以前做过的关于interger的面试题都迎刃而解。
今天以面试题为引子
Integer a5=128;
Integer a6=128;
Integer a7=127;
Integer a8=127;
Integer a9=new Integer(127);
System.out.println(a5==a6);//false
System.out.println(a7==a8);//true
System.out.println(a9==a8);//false
System.out.println(a9.equals(a8));在程序中运行 jdk1.7的环境下 是false,大家都知道 == 比对的地址的引用(不知道的话可以自行去搜索下,网上很多的例子)
通过上面可以得到 a8 和 a9的数值相等 但是所引用的地址不是一样的。为什么呢?
首先虚拟机在编译的过程中会把代码优化一遍,也就是说上面的代码可能不是我们想要的。先看一下编译之后的代码什么样子。
(class文件反编译之后的代码)
Integer a5 = Integer.valueOf(128);
Integer a6 = Integer.valueOf(128);
Integer a7 = Integer.valueOf(127);
Integer a8 = Integer.valueOf(127);
Integer a9 = new Integer(127);
System.out.println(a5 == a6);
System.out.println(a7 == a8);
System.out.println(a9 == a8);
System.out.println(a9.equals(a8));
大家可以看到 编译器优化之后真正运行的代码是这样子的。=128 优化成了 Integer.valueOf(128).
然而 Integer.valueOf做了什么事情呢?怎么会 两个128相比较会是不同的对象 两个127 相比较就是相同的数据呢?
带着疑问翻开了jdk源码(大家可以用 intellij idea 直接查看源码)
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
首先第一眼看过去这是个静态的方法,通过Interger对象可以直接调用。看里面的内容,第一次看的时候猜想了作者的意思,大约是判断传送过来的i的数据 是否在 IntegerCache.low 和 IntegerCache.high中间,如果在的话返回一个IntegerCache.cache[i + (-IntegerCache.low)]。如果不在的话 new 一个对象。接着顺藤摸瓜,看下上面这3个东西是什么。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
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) {
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);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
研究了代码发现,IntegerCache 是一个静态的 私有的方法,里面有很多的静态对象,静态是什么?简单的可以认为全局变量,谁都可以用,被缓存的数据。low 是 -128 high 默认是127 也可以配置,上面的意思是在程序启动的时候,初始化一部分数据存在内存中,这些数据是什么呢?
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
大家可以看到 这里进行了一次for循环,里面有个new 关键字(new 就是在堆中分配一块内存),每次都创建一个对象,内 容是 low和high 中间的所有数据面也就是 (-128)到(127)中的数据,共255 Interger对象,新建了这些对象之后,吧他们的地址的引用存在了static final Integer cache[]; 中,这是一个数据,而且是静态的存在了缓存中,且不可变。
好了明白这些数据之后 再回过头来看下上面的代码所表达的意思。
Integer.valueOf(i)中,判断传送过来的i 是否在 -128 和127 中间,如果在就返回return IntegerCache.cache[i + (-IntegerCache.low)]; 不在就返回 一个new 对象。
所以当
Integer.valueOf(128)的时候 比 127大 ,每次都是new 一个新的对象,
Integer.valueOf(127)的时候 等于127,就从缓存中拿出127的地址,不用新建一个对象了。
所以
System.out.println(a5==a6);//false
System.out.println(a7==a8);//true
每次new 的都是一个新的对象,不管缓存中是否存在,所以 System.out.println(a9==a8);//false
这是我看interger源码中比较有感触的地方,有不到和错误之处请说出来大家一起进步。
}
Interger对象源码解析相关推荐
- [OC学习笔记]分类和关联对象源码解析
我们平时在开发的时候经常会使用分类来添加方法.协议.属性,但在添加属性的时候属性是不会自动生成成员变量的,这时候我们就需要关联对象来动态存储属性值. 分类 @interface NSObject(St ...
- String str = new String(abc)创建了几个对象?结合源码解析
String str = new String("abc")创建了几个对象?结合源码解析 首先,我们看一下jdk源码: 1 /** 2 * Initializes a newly ...
- 网络请求框架:Okhttp:Call对象实现请求源码解析【四】
OKHttp3--调用对象RealCall源码解析[四]_没有鱼了的博客-CSDN博客 一:概述,当我们封装好 Request后需要执行这个请求,但是 OkHttp并不是直接执行 Request ,而 ...
- ⭐openGauss数据库源码解析系列文章—— 对象权限管理⭐
在前面文章中介绍过"9.3 角色管理整",本篇我们介绍第9章 安全管理源码解析中"9.4 对象权限管理"的相关精彩内容介绍. 9.4 对象权限管理 权限管理是安 ...
- Unity中的UGUI源码解析之图形对象(Graphic)(2)-ICanvasElement
Unity中的UGUI源码解析之图形对象(Graphic)(2)-ICanvasElement 在上一篇文章中, 我们对整个Graphic部分做了概述, 这篇文章我们介绍ICanvasElement和 ...
- Spring4.x源码解析:JDK动态代理成生成代理对象源码
@Component("aopTestBean") class AopTestBean implements AopTestBeanInterface{public void ao ...
- 谷歌BERT预训练源码解析(三):训练过程
目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...
- libev源码解析——定时器监视器和组织形式
我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...
- libev源码解析——调度策略
在<libev源码解析--监视器(watcher)结构和组织形式>中介绍过,监视器分为[2,-2]区间5个等级的优先级.等级为2的监视器最高优,然后依次递减.不区分监视器类型和关联的文件描 ...
最新文章
- 在html利用canvas蚂蚁,html5 利用canvas实现简单的人物走动
- Getting Started With setuptools and setup.py
- 百度搜索打不开第二页_北易信息:百度爱采购适合做优化推广吗
- 在mysql中更改数据类型_如何在MySQL中更改列的数据类型?
- 入门话题1. 在Web中控制图的显示外观?把一张500*800 的图, 显示成180*110 的小图....
- Qt实现延时sleep函数功能
- WorldWind源码剖析系列:可渲染对象类RenderableObject
- python 列表写入csv_Python将字典数据写入CSV文件
- 《软技能:代码之外的生存指南》一一21.3 打造成功博客的秘诀
- 【Cisco技术资料汇总】
- C# C++ 共享内存 结构体读写 结构体中嵌套结构体 结构体中带string Char*的处理方式
- solidworks图纸模板添加_solidworks工程图模板制作教程(中)
- Python Matplotlib add_subplot 和 subplots_adjust详解及代码详细说明 配图片说明
- [转帖]16nm国内最先进 兆芯展示x86 KX-6000八核处理器
- 敏捷管理 -- 时间和成本管理
- 百度编辑器抓取微信图片并替换内容
- Adobe XMP SDK项目应用(续1)
- 网站SEO的技巧都有哪些?快速增加权重靠谱吗?
- php输出3d彩票号码,3D彩票开出罕见“豹子号“!彩票中心要“赔钱”
- JavaScript网页生日快乐