Hold住面试官之Integer Cache

Stella981
• 阅读 454

前言

最近跟许多朋友聊了下,在这个“跳槽”的黄金季节,大家都有点蠢蠢欲动,所以最近就多聊聊面试的时候需要注意的一些问题,这些问题不一定多深奥,多复杂,但是一不注意的话却容易掉坑。下面看一下面试的时候经常遇到的一段代码:

public class IntegerDemo {
    public static void main(String[] args) {
        Integer numA = 127;
        Integer numB = 127;

        Integer numC = 128;
        Integer numD = 128;

        System.out.println("numA == numB : "+ (numA == numB));
        System.out.println("numC == numD : "+ (numC == numD));
    }
}

根据大家以往的经验,会认为上面的代码用“==“符号来比较,对比的是对象的引用,那么ABCD是不同的对象,所以输出当然是false了。我在《“==”、“equals()”、“hashcode()”之间的秘密》这篇文章也讨论过。那么事实也是如此吗?下面看一下输出结果:

numA == numB : true
numC == numD : false

What?这个输出结果怎么跟以往的认知有所出入呢?在我们的代码“Integer numA = 127”中,编译器会把基本数据的“自动装箱”(autoboxing)成包装类,所以这行代码就等价于“Integer numA = Integer.valueOf(127)”了,这样我们就可以进入valueOf方法查看它的实现原理。

//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);
}

//Integer静态内部类
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) {
    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;
            }
    
    private IntegerCache() {}
        }

从上面的源码可以看到,valueOf方法会先判断传进来的参数是否在IntegerCache的low与high之间,如果是的话就返回cache数组里面的缓存值,不是的话就new Integer(i)返回。

那我们再往上看一下IntegerCache,它是Integer的内部静态类,low默认是-128,high的值默认127,但是high可以通过JVM启动参数XX:AutoBoxCacheMax=size来修改(如图),如果我们按照这样修改了,然后再次执行上面代码,这时候2次输出都是true,因为缓存的区间变成-128~200了。

Hold住面试官之Integer Cache

但是如果我们是通过构造器来生成一个Integer对象的话,下面的输出都是false。因为这样不会走ValueOf方法,所以按照正常的对象对比逻辑即可。

public class IntegerDemo {
    public static void main(String[] args) {
        Integer numA = new Integer(127);
        Integer numB = new Integer(127);

        Integer numC = new Integer(128);
        Integer numD = new Integer(128);

        System.out.println("numA == numB : "+ (numA == numB));//false
        System.out.println("numC == numD : "+ (numC == numD));//false
    }
}

还有需要注意的一点是,此类缓存行为不仅存在于Integer对象。还存在于其他的整数类型Byte,Short,Long,Character。但是能改变缓存范围的就只有Integer了。

结语

有时候往往越简单的知识越容易掉坑里,所以要保持自己的求知欲,不断巩固的基础,才能让自己在面试的时候不会栽跟头。

Hold住面试官之Integer Cache

喜欢的话~关注一下微信公众号《深夜里的程序猿》,每天分享最干的干货


文章推荐

Redis的正确使用姿势

一文彻底搞懂面试中常问的各种“锁”

那些年我们一起踩过的Dubbo坑

点赞
收藏
评论区
推荐文章
我是阿沐 我是阿沐
3年前
Redis发布订阅:最简单最通俗的文章
前言可能小伙伴的工作年限大部分已经超过三年甚至四年五年,不知道是否有一种危机感,我们写了那么多的需求代码没有20w行也有个10w行了吧,但是出去找工作的时候不是笔试被pass掉就是面试被pass,你会发现好多你只是知道但是回答不上来。这个时候你才知道去补习知识点,其实这种做法对自身发展不太友好的。我去年疫情期间,在大家都不敢跳槽季节我义无反顾选择跳槽,进入大
我是阿沐 我是阿沐
3年前
百度后端二面有哪些内容,万字总结(一)
前言这是最近一位老朋友去百度面试,应该是面试资深工程师岗位,他跟我讲被问到mysql索引知识点?其实面试官主要还是考察对mysql的性能调优相关,问理论知识其实也是想知道你对原理的认知,从而确认你是否有相关的调优经验。朋友说他回答的还行,然后很顺利进行了三面四面。那么本文将跟大家一起来聊一聊这个如何回答面试官的这个问题!公众号:我是阿沐以下是自己的理解
我是阿沐 我是阿沐
3年前
运维大佬嘲笑我,这个你都不知道?
大家好,我是阿沐,一个喜欢分享技术而且爱好写散文的程序员。今天来给大家介绍一下info命令查看redis具体的详细信息讲解!起因是:前几年我在老家郑州实习面试(那个时候还没有毕业)的时候遇到面试官提问;面试官来于百度总部的工程师6年java开发经验3年多的PHP开发经验,我在他的面前基本就是弟弟中的弟弟,虽然勉强通过入职了,但是却被运维无情地嘲笑,就因为组
Wesley13 Wesley13
3年前
Java面试集锦
各位学习Java的同学看过来了,以下是CSDN作者「ThinkWon」总结的面试题。希望对在准备跳槽或者找工作的同学有点帮助。这一波面试题总体来说基本上能够回答面试官的70%问题。虽然有些小节不够完善的,只能靠你自己多面试多总结了。序号内容链接地址1Java基础知识面试题(2020最新版)https://thinkwon.bl
可莉 可莉
3年前
2020最新Web前端经典面试题及答案
本篇收录了一些大厂面试中经常会遇到的经典面试题,并且我做好了整理分类。虽然今年的金九银十已经过去了,但是可以为明年的金三银四做装备啊,相信每一个跳槽季都有很多的前端开发者蠢蠢欲动,通过对本篇知识的整理以及经验的总结,希望能帮到更多的前端面试者。好了,那我接下来就开始正文咯。PS:内容超长,请注意!HTML篇1.你是怎么理解HTML
Stella981 Stella981
3年前
Android之ListView原理学习与优化总结
在整理前几篇文章的时候有朋友提出写一下ListView的性能优化方面的东西,这个问题也是小马在面试过程中被别人问到的…..今天小马就借此机会来整理下,网上类似的资料蛮多的,倒不如自己写一篇,记录在这个地方,供自己以后使用,不用再翻来翻去的找了,用自己写的…呵呵,不多讲其它了,说起优化我想大家第一反应跟小马一样吧?想到利用ViewHolder来优化List
Stella981 Stella981
3年前
2020最新Web前端经典面试题及答案
本篇收录了一些大厂面试中经常会遇到的经典面试题,并且我做好了整理分类。虽然今年的金九银十已经过去了,但是可以为明年的金三银四做装备啊,相信每一个跳槽季都有很多的前端开发者蠢蠢欲动,通过对本篇知识的整理以及经验的总结,希望能帮到更多的前端面试者。好了,那我接下来就开始正文咯。PS:内容超长,请注意!HTML篇1.你是怎么理解HTML
Stella981 Stella981
3年前
Git神作!2021年Java春招高级面试指南,吃透至少P7
马上到今年的金三银四了,又是跳槽的好季节,准备跳槽的同学都摩拳擦掌准备大面好几场,今天为大家准备了互联网面试必备的1到5年Java面试者都需要掌握的面试题,分别JVM,并发编程,MySQL,Tomcat,网络与IO及Spring系列等等,可以说掌握这些薪资涨10K还是可以的!今天分享给大家的都是目前主流企业使用最高频的面试题库,也都是Java
Stella981 Stella981
3年前
2020年最新阿里、字节、美团、拼多多等一线大厂前端岗高频面试真题合集,面试轻松无压力
前言找工作还是需要大家不要紧张,干我们这一行的接触人本来就不多,难免看到面试官会紧张,主要是因为怕面试官问的问题答不上来,那时候不要着急,答不上了的千万不要胡扯一些,直接就给面试官说这块我还没接触到,以后如果工作当中遇到的话我可以很快的把这个问题给解决了,但是我们有了这篇文章,就不一样了,大厂面试的知识的点基本都有涉及,而大厂又是行业的标杆,多
可莉 可莉
3年前
2020年最新阿里、字节、美团、拼多多等一线大厂前端岗高频面试真题合集,面试轻松无压力
前言找工作还是需要大家不要紧张,干我们这一行的接触人本来就不多,难免看到面试官会紧张,主要是因为怕面试官问的问题答不上来,那时候不要着急,答不上了的千万不要胡扯一些,直接就给面试官说这块我还没接触到,以后如果工作当中遇到的话我可以很快的把这个问题给解决了,但是我们有了这篇文章,就不一样了,大厂面试的知识的点基本都有涉及,而大厂又是行业的标杆,多