学习的本质就是一个赋值的过程,用新知识来覆盖你的旧知识或者无知(null)。掌握知识是自己的, 分享知识,才能帮助更多的人,创造更大的价值。学贵以恒,以此自勉,与君共享。----曦阳X

上次在博客园看到有关IntegerCache的文章,回想起之前一次面试的时候也遇到过这种题,当时知道有IntegerCache这个东西会缓存-128到127之间的数据,但并没有深入研究下,因此今天再深入分析下这个类,先看看下面一段代码:

Integer int1 = 20;

Integer int2 = 20;

Integer int3 = 128;

Integer int4 = 128;

Integer int5 = new Integer(20);

System.out.println(int1 == int2);

System.out.println(int3 == int4);

System.out.println(int1 == int5);

如果不了解Integer内部的缓存机制,可能会对此一脸懵逼:这还有啥好比较的,20和128都是常量,前2个肯定都是true,Integer是对象类,每次new出来的对象都应该在不同的内存中,== 比较连地址都不等,肯定都是false。事实上,如果你真这么想就错了。

其实按照上学时的经验我们也会怀疑:这么简单肯定有问题,出题人这么傻会出个这种题?没错,越是简单的地方往往越容易采坑,今天就来谈谈Integer中的静态类IntegerCache问题。

先说下上面的答案:true,false,false;后面再分析原因。

下面是Integer中的静态类IntegerCache的源码,我们来一点点分析:

IntegerCache的源码其实很简单,就是定义了一个high和一个low上下限,这2个值就是用于存储Integer的缓存对象,目的也很明确:提高内存理由率和效率,类似的缓存机制还有8种基本数据类型中除了Double和Float外的6种,比如ShortCache,ByteCache等,而之所以Double和Float没有缓存机制,是因为double、float是浮点型的,没有经常使用到的数据,缓存效果没有其它几种类型使用效率高。除了IntegerCache稍复杂,其他都很简单。不得不说,JDK的作者个个都是天才,代码写得由简洁又巧妙,当然好多代码功力不够也不太好看懂。

还有就是定义了一个Integer类型的Cache数组,目的就是存放缓存的Integer对象。下面看下static静态代码块。

  static {    // high value may be configured by property    int h = 127;
    //意味着可以通过JVM参数java.lang.Integer.IntegerCache.high来设置缓存的最大值
    String integerCacheHighPropValue =        sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");  
    if (integerCacheHighPropValue != null) {        try {
            //如果设置了Cache的最大值,就将该最大值与127比较,取其中较大的一个作为缓存的最大值。意味着假如设置的最大值为100,那其实是不会生效的,这么做估计是为了尽可能利用缓存,达到整体性能较好,当然最大值也不能超过Integer.MAX_VALUE
            int i = parseInt(integerCacheHighPropValue); 
            i = Math.max(i, 127);            // Maximum array size is Integer.MAX_VALUE
            //这里得到的h是新建Integer数组的Size,因为low是-128,所以low前面要带个-号,其实就是相加,-1是把0也算上
            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;    //初始化IntegerCache    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;
    //私有构造方法    private IntegerCache() {}
}   通过上面分析,我们知道IntegerCache存的其实默认就是-128到127之间的256个Integer对象,这些对象是存在java常量区的。当执行Integer int1 = 20的时候,编译器会自动进行装箱操作,实际执行了Integer.valueOf(int i)方法,同样的,如果是拆箱操作,执行的就是Integer.intValue()方法,下面来看看valueOf(int i)方法的源码:

      

这么看就很清晰了,当进行自动装箱的时候,会先判断这个值是否在IntegerCache的low和high之间,如果在,就返回IntegerCache中缓存的Integer对象,再来看看开始的题目:

20是在-128到127之间,因此不会新建对象,都是IntegerCache中的对象,因此int1和int2相等

同理:128超过了IntegerCache.high,因此新建了2个不同的对象(存在堆区,在JVM内存中地址不等),所以int3 == int4 为false

至于int1 和int5,由于int1是存在java常量区,int5是存在java的堆区,因此2者也不相等,故也是false。

结尾:看到这个静态内部类,又想发散下静态内部类的加载时间和机制,以及java中静态导入的问题,下次再来讲讲这2个问题

谈谈Integer中的静态类IntegerCache相关推荐

  1. LongCache机制与Long等值比较\\\\Integer 中的缓存类IntegerCache

    转载自https://www.cnblogs.com/wellmaxwang/p/4422855.html https://blog.csdn.net/louistech/article/detail ...

  2. Integer 中的缓存类IntegerCache

    2014年去某公司笔试的时候遇到这么一道题: public class Test {public static void main(String[] args) {Integer int1 = Int ...

  3. Java 基本数据类型的强制转换和自动转换,基本数据类型包装类,Integer常用方法,Integer中equals和==的区别

    文章目录 基本数据类型的自动转换 基本数据类型的强制转换 包装类(封装类) Integer类中的方法 一:Number中的xxxValue()方法 二:Integer.parseInt("S ...

  4. html js脚本限制 正则,简单谈谈JS中的正则表达式

    1.正则表达式包括两部分 ①定义正则表达式的规则: ②正则表达式的模式(i/g/m): 2.声明正则表达式 ① 字面量声明: var reg = /表达式规则/表达式模式: eg:var reg = ...

  5. Linux存储保护,谈谈Linux中的存储保护

    谈谈Linux中的存储保护 以下讨论的内容是以i386平台为基础的 Linux将4G的地址划分为用户空间和内核空间两部分.在Linux内核的低版本中(2.0.X),通常0-3G为用户空间,3G-4G为 ...

  6. 谈谈JAVA中的安全发布

    谈谈JAVA中的安全发布 昨天看到一篇文章阐述技术类资料的"等级",看完之后很有共鸣.再加上最近在工作中越发觉得线程安全性的重要性和难以捉摸,又掏出了<Java并发编程实战& ...

  7. java的static类_java中staticclass静态类详解

    一般情况下是不可以用static修饰类的.如果一定要用static修饰类的话,通常static修饰的是匿名内部类. 在一个类中创建另外一个类,叫做成员内部类.这个成员内部类可以静态的(利用static ...

  8. Spark精华问答 | 谈谈spark中的宽窄依赖

    总的来说,Spark采用更先进的架构,使得灵活性.易用性.性能等方面都比Hadoop更有优势,有取代Hadoop的趋势,但其稳定性有待进一步提高.我总结,具体表现在如下几个方面. 1 Q:Spark ...

  9. 谈谈C#中的三个关键词new , virtual , override

    谈谈C#中的三个关键词new , virtual , override C#支持单继承,说到继承就不得不说new,virtual和override这三个关键词,灵活正确的使用这三个关键词,可以使程序结 ...

  10. 谈谈java中成员变量与成员方法继承的问题

    谈谈java中成员变量与成员方法继承的问题 关于成员变量和成员方法的的继承问题,我也可以做一个小测试,来看看结果. 首先我们先创建一个父类: 其次再创建一个子类,子类中要比父类中少一个成员方法: 这样 ...

最新文章

  1. 一篇SSM框架整合友好的文章(二)
  2. Ubuntu14.04安装nvidia-docker2
  3. javaweb使用 数据库连接池 DBCP,实现对数据库驱动使用优化,多个 action共用一个数据库连接
  4. MSP430F5529 DriverLib 库函数学习笔记(十五)SFR 模块
  5. python无法安装第三方库read time out_解决pip install的时候报错timed out的问题
  6. 2021年中国电竞运动行业发展报告
  7. 深度学习自学(二十四):华为Atlas人工智能计算平台
  8. 硬盘出错,导致文件坏了
  9. 树莓派人脸识别源代码
  10. SpringBoot入门学习
  11. 连接共享打印机0x0000011b win10
  12. 第六章第三十题(游戏:双骰子赌博)(Game: craps)
  13. 数字图像处理与Python实现-图像降噪-指数型低通滤波
  14. Objective-C 【对象-多文件开发简介】
  15. redis的incr+expire的坑
  16. 机器学习必备算法之(一)逻辑回归(logistics regression)及Python实现
  17. 从python开始学编程pdf-Python真好玩:教孩子学编程 PDF 完整原版
  18. python的opencv操作记录12——Canny算子使用
  19. Spring原码讲解
  20. System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。...

热门文章

  1. 正态分布下贝叶斯决策的引入
  2. mysql建三行三列表格_基于另一个表中列的名称在mysql中创建表
  3. 2021-09-02二叉树的中序遍历
  4. 线下商店销量预测挑战赛
  5. android记事本的app,自己编写的Android记事本APP软件
  6. python3.6下载opencv_ubuntu16.04+anaconda3+python3.6安装OpenCV3
  7. 机器学习算法篇:谈Softmax激活函数以及Softmax回归和Logistic回归关系
  8. 【2011-2012 ACM-ICPC Pacific Northwest Regional Contest】Collateral Cleanup【建图拓扑排序】
  9. 教师计算机培训心得体会范文,教师计算机教育培训学习心得体会
  10. PHP获取真实客户端的真实IP REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR