一线大厂面试真题——Integer a1 =100 Integer a2 =100 ,a1 ==a2?的运行结果?

80 阅读2分钟

概述

一个工作了3年的同学去面试遇到这样一个问题。

“Integer a1 =100、  Integer a2 =100 ,请问a1==a2的运行结果以及为什么?”

考察目的

这个问题主要考察Java基础知识,涉及到的知识点还挺多的。

比如,==号表示的内存地址匹配、装箱拆箱、Integer内部内部的设计原理。

大部分同学能够熟练使用Integer,但是不一定去了解过原理,但是作为一个3年以上的开发。

对于Java基础必须要知其然还得知其所以然。

问题分析

按照大家对于Java基础的认知,两个独立的对象用==进行比较,是比较两个对象的内存地址。

那得到的结果必然是false。但是在这个场景中,得到的结果是true。为什么呢?

首先,Integera1=100,把一个int数字赋值给一个封装类型,Java会默认进行装箱操作,也就是调用Integer.valueOf()方法,把数字100包装成封装类型Integer。

其次,在Integer内部设计中,用到了享元模式的设计,享元模式的核心思想是通过复用对象,减少对象的创建数量,从而减少内存占用和提升性能。

Integer内部维护了一个IntegerCache,它缓存了-128到127这个区间的数值对应的Integer类型。

一旦程序调用valueOf方法,如果数字是在-128 到  127 之间就直接在 cache 缓存数 组中去取 Integer 对象。否则 ,就会创建一个新的对象。

所以,对于这个面试题来说,两个 Integer 对象 ,因为值都是 100,并且默认通过装箱 机制调用了 valueOf 方法。

从 IntegerCache 中拿到了两个完全相同的 Integer 实例。

因此用等号比较得到的结果必然是 true。

问题解答

a1 ==a2 的执行结果是 true。

原因是Integer内部用到了享元模式的设计,针对-128到127之间的数字做了缓存。 使用 Integer a1 =100 这个方式赋值时 ,Java 默认会通过 valueOf 对 100 这个数字进 行装箱操作,从而触发了缓存机制,使得a1和a2指向了同一个 Integer 地址空间。

总结

注意,这个基础知识非常重要,如果有些同学在工作中直接把两个 Integer 封装类型用 等号去比较,就有可能导致生产故障。

所以大家在写程序的时候 ,一定要对用到的 api 和技术框架的实现有一定的了解不仅仅是为了面试 ,而是为了提升编码和架构设计能力。