int和Integer自动装箱和拆箱

文章目录

      • int和Integer的区别:
      • int和Integer比较的特性
        • == 地址比较
        • equals 数值的比较
        • 笔试题,关于 == 、 equals
      • 自动装箱和拆箱
        • Integer.valueOf() 自动装箱
        • Integer.intValue() 自动拆箱

int和Integer的区别:

  • int是基本数据类型,直接存储的数值,默认是0
  • Integer 是int的包装类,是个对象,存放的是对象的引用,必须实例化之后才能使用,默认是null

int和Integer比较的特性

== 地址比较

  • 数值类型int自动装箱成对象Integer,实际上是调用了Integer.valueOf(),如果数值范围在-128到127会默认从常量池获取对象,引用地址相同;超过范围会new对象出来,在堆中重新分配内存,指向这个新内存的引用地址必然不相同。

  • int 和 Integer 比较时,会自动进行Integer的拆箱操作,即比较的是数值。

  • 凡是new出来的对象,都在堆中重新分配内存,引用地址必然不相同。

equals 数值的比较

  • Integer里重写了equals()方法,比较的是value。
  • Object里默认的equals方法比较的是地址 ==
  public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

笔试题,关于 == 、 equals

//测试,结果是运行出来的哈

public static void compareInt2Integer() {
    
    /**
     * i、j实际上都是调用了 Integer.valueOf(128)
     * 都是从常量池取的,所有内存地址一样,true
     */
    Integer i = 127;
    Integer j = 127;
    System.out.println(i == j);    // true
    System.out.println(i.equals(j)); // true

    /**
     * m、n 实际上都是调用了 Integer.valueOf(128),进行自动装箱操作
     * m、n 都是新创建的对象,会在堆中重新分配内存,地址不同,false
     */
    Integer m = 128;
    Integer n = 128;
    System.out.println(m == n);   //false
    System.out.println(m.equals(n)); //true

    /**
     * k取的是缓存,h是新创建的对象,false
     */
    Integer k = 127;
    Integer h = new Integer(127);
    System.out.println(k == h);   //false
    System.out.println(k.equals(h));//true

    /**
     * new 操作符会分配内存,a、b都是新创建的对象
     * == 比较的是引用的地址,false
     */
    Integer a = new Integer(127);
    Integer b = new Integer(127);
    System.out.println(k == h);  //false
    System.out.println(k.equals(h)); //true

    /**
     * Integer.valueOf() 会优先判断常量池缓存,缓存范围是-128到127,超过范围会new一个对象,
     * w 实际也是调用了 Integer.valueOf(128)
     * w、y 都是新创建的对象 false
     */
     Integer w = 127;
     Integer y = Integer.valueOf(127);
     System.out.println(w == y); // true
     System.out.println(w.equals(y)); //true
  
    Integer w = 128;
    Integer y = Integer.valueOf(128);
    System.out.println(w == y); // false
    System.out.println(w.equals(y)); //true

    /**
     * Integer和int == 比较,Integer会自动拆箱成int,数值比较,true
     *  Integer 和 int 进行算术运算符 + - * / 等,会自动拆箱
     */
    Integer x = 128;
    int z = 128;
    System.out.println(x == z); //true
    System.out.println(x.equals(z)); //true
}

自动装箱和拆箱

1、新建一个java文件,ClassTest.java

public class ClassTest {
    public static void main(String[] args) {
        Integer i = 10;
        int a = i;
    }
}

2、打开cmd,进入ClassTest.java路径下

javac ClassTest.java   // javac,编译,生成class文件
javap -c ClassTest.class  // javap 反编译

可以看出

  • 自动装箱 是通过 Integer.valueOf()
  • 自动拆箱是通过 Integer.intValue

int和Integer自动装箱和拆箱_第1张图片

Integer.valueOf() 自动装箱

享元模式,在 -128到127区间内,共享一份实例。
IntegerCache 是 Integer里的静态内部类

//Integer.valueOf() 自动装箱
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)]; //取缓存
        return new Integer(i); //新建对象
    }

//静态内部类
 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
		//静态变量,静态块,在类加载时初始化
        static {
            int h = 127;
            //取自定义high,可配,如果没设置,默认为127
            high = h;
            cache = new Integer[(high - low) + 1]; //分配数组内存
            int j = low;
            //设置常量数组cache[],下标从0-255,存储内容为(-128)-(127) 
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

Integer.intValue() 自动拆箱

// Integer的值就是存储在这个value里面
    private final int value;
    
    public int intValue() {
        return value;
    }

参考:
深入剖析Java中的装箱和拆箱

你可能感兴趣的:(java基础)