Integer 和 int的区别

  1. int是Java的一种基本类型,Integer则是对应的包装类。
  2. Integer的默认值是null,int的默认值是0
  3. Integer变量必须实例化后才能使用,而int变量不需要
  4. Integer是引用类型、int则是直接存储数据值

问题引入

int是Java的一种基本类型,Integer则是对应的包装类,只要接触过开发,想必都不会陌生,接下来我们来看一组代码,看看跟你预期的结果是否一致呢。
图片描述

很简单的一组大小比较,接下来我们看下程序执行的结果

图片描述

看到这里,是否有点意外,跟预想中的结果有出入,如果觉得结果可能贴错了,没关系,你可以自己尝试执行一遍。是不是发现执行的结果没变,num200_0 = num200_1,num1000_0 = num1000_1 这两组值明明是相等的,为什么打印的结果却是false?我们回顾一下,Integer是什么?Integer是int的包装类,其本身不是基本数据类型,是引用数据类型,不会直接存储数据值。

看到这里,大概理解了为什么后两组的结果是false了吧,因为他们本身不是基础类型,存储的不是数据值,比较的时候,是去比较引用。

但是细心的同学会发现两个问题

  1. 这里的Integer对象是直接赋值的,没有进行new操作,例如num1000_0和num1000_1都是1000,为什么持有的引用不相等?
  2. 既然是引用类型,为什么num0_1、num0_2;num100_0、num100_1这两组值又是相等的呢?

解决问题

看到这里,从代码表面上和猜想去看的话,已经解决不了问题了,但是我们可以确定,问题一定是出现在Integer这个类上的,那么现在我们带着这两个问题来看下Integer源码。

解决问题之前,我们先来看一下Integer num1000_0 = 1000 做了什么事情
1000是int型基本数据,num1000_0是Integer类型,赋值时Java会进行自动装箱,也就是Integer num1000_0 = 1000 实际上会解释成 Integer num1000_0 = Integer.valueOf(1000)。
那么我们看下Integer.valueOf(1000)又做了什么事情。
图片描述

我们看到Integer类中有一个IntegerCache的内部类,持有一个Integer类型的缓存,默认的缓存范围是-128到127,如果传入的i值在缓存范围内,那么直接从Interger的内部IntegerCache中获取的,如果传入的i值大于缓存的范围,
那么其实是去做了new Integer(i)这个操作。

明白了这一点,那我们回过头来看下上面的问题自身

问题①

Integer num1000_0 = 1000;
Integer num1000_1 = 1000;
因为1000不在缓存范围内,所以执行的是new Integer(1000)的操作,所以num1000_0和num1000_1最终是new了两个对象,因此其引用是不相等的,所以执行结果是false

问题②

Integer num0_1 = 0;
Integer num0_2 = 0;

Integer num100_0 = 100;
Integer num100_1 = 100;

这两组值都在缓存范围内,所以num0_1、num0_2;num100_0、num100_1 这两组值都是去Integer的IntegerCache中的缓存区去拿的,因为拿的是同一个对象,所以执行结果是true。

总结

看到这里,想必对与Integer更为了解了吧,日常开发中比如为了校验int型入参是否为空、ArrayList使用等场景下,int是不能支持的,因此我们会采取Integer去替换int。
但往往在某些地方可能需要做比较的操作,就会出现类似上述问题,相等的值结果执行结果是false,导致代码流程可能走到错误的分支,因此切记使用Integer比较时,要注意值的范围,必要时使用用intValue()获取到int值之后再去进行比较。


码魇
485 声望15 粉丝