Java中Integer和int的区别

2023-12-20 19:46:34

一、介绍

各位小伙伴们无论在工作还是学习中,与Integer都有着过硬的交情,我说的没错吧,大家都知道他可以表示一个整数,而且也知道可以表示整数的还有int,只是使用Integer的次数要比int多得多,今天我们就来好好探究一下Integer与int的区别以及更深处的知识。

二、不同点

  • Integer是包装类型(即引用类型),int是基本类型

    也就是说,Integer是一个类,里面有很多方法可以使用,例如

    boolean equals(Object obj){...}
    int compareTo(Integer anotherInteger){...}
    

    而int不是一个类,能做的只有+、-、*、/、=五种运算,例如

    int a = 3;   int b = 4;   int c = a + b;
    
  • Integer的默认值是null,int的默认值是0

    在这里插入图片描述

  • Integer变量使用之前必须先实例化,int变量可以直接使用。

    Integer如果没有实例化就直接使用会报空指针异常(因默认值为null);int如果没有初始化则使用默认值0。

三、相同点

  • 取值范围相同

    最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)

    最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)

    在这里插入图片描述

    原因:众所周知,整型变量在内存中的字节数是4个字节,一个字节是8位,因此一个整型变量占据32位,且首位为0表示非负数,1表示负数

四、使用equals()==的区别

对于每个java开发人员来说,Integer的用法再熟悉不过了,但仍然会有些工作一两年的小伙伴依然搞不清楚不同情况下equals()方法和 == 等号究竟有什么结果,以至于在基础的面试过程中翻跟头体验屡试不爽。这次我们一次性把所有可能以及结果出清楚。

  • equals()

    此方法由Object类定义,在Integer类中又对其进行了重写,我们来看一下重写后的方法。

    public boolean equals(Object obj) {
            if (obj instanceof Integer) {
                return value == ((Integer)obj).intValue();
            }
            return false;
    }
    

    这个方法先判断参数对象是否继承了Integer引用类型(如果参数是int基本类型,会先将其自动装箱成引用类型),如果没有继承Integer引用类型,则返false,这个很好理解,如果数字和字符相比,那叫什么事嘛。如果继承了Integer引用类型,就先把它强转成Integer类型,再通过intValue()方法将其拆箱为int基本类型,再和value进行地址比较(==右边的value表示的是此Integer对象在常量池中的值,该值其实也是及本来想常量)。

    ? 说了一大堆,简单一句话就是equals()方法进行的是常量池中的地址是否相等。

    ? 另外一点:常量池中值相等的数据不会同时出现,常量池中只保存一份相同的值。

  • ==

    比较两个对象在内存中的地址是否相等。

下面是我们使用equals()方法和==方法来判断Integerint的区别。在此之前,我们要先知道装箱拆箱常量池对象堆内存对象两个概念:

  • 装箱

    基本数据类型变成引用类型的过程。发生在将基本数据类型赋值给引用类型的时候, 如Integer i = 5;

  • 拆箱

    引用类型变成基本数据类型的过程。发生在将引用类型和基本数据类型做运算的时候,如下所示

    Integer i = 5; 
    int j = 5; 
    System.out.println(i==j);
    
  • 常量池对象

    保存的是创建对象时的字面量,相等的字面量只保存一次

  • 堆内存对象

    保存的是new一个对象时这个对象在堆内存中的地址

声明变量使用equals()方法比较使用==比较
1Integer i = new Integer(1);
Integer j = new Integer(1);
truefalse
2Integer i = new Integer(1);
Integer j = 1;
truefalse
3Integer i = new Integer(1);
int j = 1;
truetrue
4Integer i = 1;
Integer j = 1;
truetrue
5Integer i = 1;
int j = 1;
truetrue
6int i = 1;
int j = 1;
——true
7Integer i = new Integer(128);
Integer j = new Integer(128);
truefalse
8Integer i = new Integer(128);
Integer j = 128;
truefalse
9Integer i = new Integer(128);
int j = 128;
truetrue
10Integer i = 128;
Integer j = 128;
truefalse
11Integer i = 128;
int j = 128;
truetrue
12int i = 128;
int j = 128;
——true
  • 情况1

    在Integer i = new Integer(1)的过程中,java为我们做了两件事,先在常量池中创建一个int=1的常量,再在堆内存中创建一个对这个常量的地址引用,因此在用equals()方法时比较的是常量池中int=1这个常量,自己和自己比较的结果当然为true;

    而在==运算时,直接比较了堆内存中的地址,于是比较的结果为false

  • 情况2

    在Integer j = 1的过程中,实际上是java为我们在常量池中生成了一个常量对象1,然后j对象指向这个常量对象的地址。

    equals()运算结果为true是因为比较的是常量池中对象的比较,实际上常量池中只有一个值为1的对象,即自己比较自己。

    ==运算结果为false是因为比较的是堆内存中对象j的地址和常量池中常量对象1的地址,是两个不同的地址比较

  • 情况3

    equals()运算结果为true可以参考上面的源码以及下方解释

    ==运算结果为true是因为引用类型Integer和基本数据类型int比较时,引用类型会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较,也是堆内存中常量自己与自己的地址比较

  • 情况4

    变量i与变量j指向的其实都是常量池中的常量对象1,因此equals()运算和==运算的结果都是true

  • 情况5

    与情况4相同, 如果有疑惑可在文章后面查找答案

  • 情况6

    基本数据类型只能进行加、减、乘、除、等于五种运算,没有equals()方法,==运算为true还是因为堆内存中常量自己与自己进行地址比较。

  • 情况7

    new Integer(128)会先在常量池中创建一个常量对象128,再在堆内存中保存这个常量对象的地址,Integer i = new Integer(128)中变量i指向堆内存中保存这个常量对象地址的地址,它是指向堆内存的。可以理解为两个不同的堆内存地址指向相同的常量池地址。

    equals()运算结果为true是因为比较的是常量池中的地址,而该地址只有一个,自己比较自己,结果为true

    ==运算比较的是这两个堆内存的地址,因此结果为false

  • 情况8

    equals()运算结果为true说了很多遍了,都是同一个原因

    ==运算为false是因为比较的是堆内存中两个对象的地址,原因和情况5相同,可在文章后面查找答案

  • 情况9

    与情况3相同

  • 情况10

    与情况8相同,可在文章后面查找答案

  • 情况11

    与情况3相同

  • 情况12

    与情况6相同

五、解惑

JVM中一个字节一下的整型数据(即[128,127])会在JVM启动时加载进内存,除非用new Integer()显示的创建对象,否则都是同一对象。当使用Integer i = 1时,会将1这个数字进行缓存,下次再运行Integer j = 1时,就会直接从缓存中取,就不会new了, 这样取到的1 地址也是相同的, ==判断返回true

对于-128 ~ 127范围之外的数 实际上就是new得到的, 地址不同==判断为false

java在编译Integer i = 100 ;时,java内部会将其翻译成为Integer i = Integer.valueOf(100)

所以关键就是看valueOf()函数了。JDK源码的valueOf()是这样的

在这里插入图片描述

到此,Integer与int运算时的迷之操作总算解释清楚了,如果有需要指正或者补充的,请小伙伴们扫下方二维码关注公众号并在后台留言,我会及时给予回复,让我们一起把java学到荒,头发掉到光。



纸上得来终觉浅,绝知此事要躬行。

————————我是万万岁,我们下期再见————————

文章来源:https://blog.csdn.net/qq_36234720/article/details/135113906
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。