主题使用方法:

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

```

想想,会打印什么内容,似乎并不容易回答出来,里面有几层小坑坑,待我细细分析。

先看看运行结果!为什么会这样呢?

JAVA int比較 java int和integer比较_JAVA int比較

三、分析

我们先逐句分析一下每行代码在执行以后到底发生了什么!

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。 ```

四、总结

  1. 对于基础类型int,==都是数值比较。
  2. Integer和int的变量进行比较,==都按照数值比较。
  3. 直接为Integer赋基础类型数值,要考虑到数值的范围,是不是在常量池[-128,127]范围内。 言而总之,对于==,基础类型,比较值;引用类型比较引用的对象。

五、拓展

上文我们了解Integer常量池(缓存)机制的知识点,由此发散思维,是否其它的基础类型的包装类有类似的机制。 答案是肯定的,我们常用的ShortLongByteCharacter都有类似的机制,碍于篇幅,具体细节不一一细讲,留个同志们去研究研究。 除开基础类型的包装类,还有一个String类型很特殊,后文再细讲它的内存分配以及变量比较。