• int i = 1,Integer j = new Integer(1)即Integer j= 1;问 i==j 吗?为什么?


    java中,每个基本数据类型都是与类(包装类)相对应的:

    int对应的类是Integer;char对应的类是Character;float对应的类是Float;long对应的类是Long

    byte对应的类是Byte;short对应的类是Short;double对应的类是Double;boolean对应的类是Boolean

    一、
    1)int则是java的一种基本数据类型,其定义的是基本数据类型变量 ;Integer是int的包装类,其定义的是引用类型变量
    2)基本数据类类型存的是数值本身;引用类型变量在内存放的是数据的引用()
    3)  基本类型比较的是他们的值大小(通过==),而引用类型比较的是他们的引用地址
    4)  Integer变量必须实例化后才能使用,而int变量不需要
    5)Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
    6)Integer的默认值是null,int的默认值是0
    二、
    Integer和int的比较
    1)由于Integer变量实际上是对一个Integer对象的引用,所以两个通过new生成的Integer变量永远是不相等的(因为new生成的是两个对象,其内存地址不同)。
    Integer i = new Integer(1);
    Integer j = new Integer(1);
    System.out.print(i == j); //false
    2)Integer变量和int变量比较时,只要两个变量的值是向等的,则结果为true(因为包装类Integer和基本数据类型int比较时,java会自动将Integer拆箱为int,然后进行比较,实际上就变为两个int变量的比较)
    Integer i = new Integer(1);
    int j = 1;
    System.out.print(i == j); //true
    3)非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。(因为非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同)
    Integer i = new Integer(1);
    Integer j = 1;
    System.out.print(i == j); //false
    4)对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false
    Integer i = 110;
    Integer j = 110;
    System.out.print(i == j); //true(因为-128到127java已经进行了缓存,所以i和j指向的是同一块内存,即同样的引用地址)
    Integer i = 128;  
    Integer j = 128;
    System.out.print(i == j); //false
    java在编译Integer i = 110 ;时,会翻译成为Integer i = Integer.valueOf(100);,而java API中对Integer类型的valueOf的定义如下:
    public static Integer valueOf(int i){
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high){
            return IntegerCache.cache[i + (-IntegerCache.low)];
        }
        return new Integer(i);
    }
    java对于-128到127之间的数,会进行缓存,Integer i = 127时,会将127进行缓存,下次再写Integer j = 127时,就会直接从缓存中取,就不会new了

     三、

    举例:

     注意:

    ①Integer与new Integer不会相等。不会经历拆箱过程,
    ②两个都是非new出来的Integer,如果数在-128到127之间则是true,否则为false ;java在编译Integer i2 = 128的时候,
    被翻译成 Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存
    ③两个都是new出来的,引用地址不同,false
    ④int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比

     解析:

    A: Integer 与 int 比较的时候将Integer拆箱转成int,然后再比较大小,true
    B: Integer i01 = 59;默认处理Integer i01 =Integer.valueOf(59); i01与 i03数值在-128 - 127之间,所以在cache缓存中获取Integer对象,他们引用地址是一样的。true 
    C: i03获取的是cache中缓存好的的Integer地址,而i04是重新在堆中创建一个地址,所以两个地址是不一样的 .false
    D:同A

    其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
            我们分四种情况来讨论:
            1) Integer与int类型的赋值
                    a.把Integer类型赋值给int类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
                    b.把int类型赋值给Integer类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
            2) Integer与int类型的比较
                    这里就无所谓是谁与谁比较了,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
            3) Integer之间的比较
                    这个就相对简单了,直接把两个引用的值(即是存储目标数据的那个地址)进行比较就行了,不用再拆箱、装箱什么的。
            4) int之间的比较
                    这个也一样,直接把两个变量的值进行比较。
            值得注意的是:对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。

     四、

    堆和栈的区别是什么?
    堆和栈是编译器划分的内存空间。      
    栈上分配的内存,编译器会自动收回;堆上分配的内存,要通过free来显式地收回。      
    栈是系统自动分配,堆是需要程序员自己申请(new出来)

         
    哪些变量会在栈中分配空间,哪些变量会在堆中分配空间?      
    函数局部变量、参数,一些临时对象都在栈中分配空间。全局变量存储在堆中分配空间。 

  • 相关阅读:
    第一个SpringBoot
    windows 安装 mysql 及部分命令
    别让猴子跳回背上
    windows环境下基于Anaconda安装Tensorflow
    spark
    ubuntu环境下安装chrome
    前言
    模型压缩(4)
    模型压缩(3)
    模型压缩(2)
  • 原文地址:https://www.cnblogs.com/cdlyy/p/12512277.html
Copyright © 2020-2023  润新知