主题使用方法:https://github.com/xitu/juejin-markdown-themes
theme: juejin
highlight: github
一、引言
在java语言中,众所周知,int是基础类型,Integer是int的包装类型,属于引用类型。面试中,一般会问到两者有什么区别,答案无非就是侧重描述基础类型和引用类型的区别,这个很简单。面试难度升级就是用 ==
进行比较两者,接下来就展开讨论一下这道面试题。
二、题
```java Integer a = new Integer(3); //@1 Integer b = 3; //@2 int c = 3; //@3 int h = 3; //@4 Integer d = 3; Integer e = 300; Integer f = 300;
System.out.println(c == h);
System.out.println(a == b);
System.out.println(a == c);
System.out.println(b == d);
System.out.println(e == f);
```
想想,会打印什么内容,似乎并不容易回答出来,里面有几层小坑坑,待我细细分析。
先看看运行结果!为什么会这样呢?
三、分析
我们先逐句分析一下每行代码在执行以后到底发生了什么!
Integer a = new Integer(3); //@1
Integer
是引用类型对象,所以new
对象这个过程,先是在栈
上创建了变量a
,然后在堆
上创建对象存储数值3,最后将变量a
指向在堆上分配的地址。 Integer b = 3; //@2
这行代码直接将基础类型的值赋值给引用类型b
,这儿就涉及到装箱
的知识点。此行代码执行的时候会触发Integer.valueOf(int i)
这个Integer
自带方法。方法内容如下: public static Integer valueOf(int i) { //此处便是常量池,Integer的常量池范围为[-128,127] if (i >= IntegerCache.low && i <= IntegerCache.high) //如果i变量的值在常量池范围内,则直接使用常量池的值 return IntegerCache.cache[i + (-IntegerCache.low)]; //如果i变量的值不在常量池的范围内,堆上新分配空间存储 return new Integer(i); }
根据Integer
源码分析,因为3的值在[-128,127]范围内,所以执行这段代码,会先在栈
上创建变量b
,然后将变量指向常量池中3。 int c = 3; //@3 int h = 3; //@4
上述代码,因为int
是基础类型,所以执行@3
行代码时,会先在栈上创建变量c
,然后查找栈上有无数值3,没有存储3,然后使变量c
指向它。 执行@4
时候,执行流程大致与@3
一致,只是因为执行到这句时,数值3在栈上已存在,所以直接使变量h指向已创建好的数值3。
所以结果分析就很明了。 ``` System.out.println(c == h);//对于基础类型int,==都是数值比较,肯定是true
System.out.println(a == b);//因为两个变量都是引用类型,所以==比较引用的对象。 变量a引用的对象存储在堆上,变量b引用的对象在常量池,所以为false。
System.out.println(a == c);//Integer类型跟int类型比较,都按照基础类型的比较(拆箱)。因为数值相等,所以为true。
System.out.println(b == d);//因为数值的范围都在[-128,127],所以两个变量指向的对象都是常量池。所以为true。
System.out.println(e == f);//因为范围都超出[-128,127],所以两个变量指向的对象都是在堆各自新创建的堆对象。所以为false。 ```
四、总结
- 对于基础类型int,==都是数值比较。
- Integer和int的变量进行比较,==都按照数值比较。
直接为Integer赋基础类型数值,要考虑到数值的范围,是不是在常量池[-128,127]范围内。 言而总之,对于
==
,基础类型,比较值;引用类型比较引用的对象。五、拓展
上文我们了解
Integer
常量池(缓存)机制的知识点,由此发散思维,是否其它的基础类型的包装类有类似的机制。 答案是肯定的,我们常用的Short
、Long
、Byte
、Character
都有类似的机制,碍于篇幅,具体细节不一一细讲,留个同志们去研究研究。 除开基础类型的包装类,还有一个String
类型很特殊,后文再细讲它的内存分配以及变量比较。