面试回答

Java 中有8种基本数据类型,这些基本类型又都有对应的包装类。

因为 Java 是一种面向对象语言,很多地方都需要使用对象而不是基本数据类型。比如,在集合类中,我们是无法将 int、double 等类型放进去的。因为集合的容器要求元素是 Object 类型。

为了让基本类型也具有对象的特征,就出现了包装类型,它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

知识扩展

基本类型和包装类型的区别

  1. 默认值不同,基本类型的默认值为0,false或\u0000等,包装类默认为 null
  2. 初始化方式不同,一个需要new,一个不需要
  3. 存储方式不同,基本类型保存在栈上,包装类对象保存在堆上(通常情况下,在没有JIT优化栈上分配时)

如何理解自动拆装箱

拆箱与装箱

包装类是对基本类型的包装,所以,把基本数据类型转换成包装类的过程就是装箱;反之,把包装类转换成基本数据类型的过程就是拆箱

自动拆装箱

在 Java SE5 中,为了减少开发人员的工作,Java 提供了自动拆箱和自动装箱的功能。

自动装箱:就是将基本数据类型自动转换成对应的包装类。

自动拆箱:就是将包装类自动转换为对应的基本数据类型。

        Integer i=1; //自动装箱
        int x=i;     //自动拆箱

自动拆装箱原理

自动装箱都是通过包装类的 valueOf() 方法来实现的。自动拆箱都是通过包装类对象的 xxxValue() 来实现的。

如:int 的自动装箱都是通过 Integer.valueOf() 方法来实现的,Integer 的自动拆箱都是通过 integer.intValue() 来实现的。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

    public int intValue() {
        return value;
    }

哪些地方会自动拆装箱

我们了解原理之后,再看一下,什么情况下,Java 会帮我们进行自动拆装箱。前面提到的变量的初始化和赋值的场景就不介绍了,那是最简单的也最容易理解的。

我们主要来看一下,那些可能被忽略的场景。

场景一:将基本数据类型放入集合类

我们知道,Java 中的集合类只能接收对象类型,那么以下代码为什么会不报错呢?

    List<Integer> list=new ArrayList<>();
    for (int i = 0; i < 50; i++) {
        list.add(i);
    }

将上面代码进行反编译,可以得到以下代码:

    List<Integer> list=new ArrayList<>();
    for (int i = 0; i < 50; i++) {
        list.add(Integer.valueOf(i));
    }

以上,我们可以得出结论,当我们把基本数据类型放入集合类中的时候,会进行自动装箱。

场景二:包装类型和基本类型的大小比较

有没有人想过,当我们对 Integer 对象与基本类型进行大小比较的时候,实际上比较的是什么内容呢?看一下代码:

    Integer a=1;
    System.out.println(a==1?"等于":"不等于");
    Boolean bool=false;
    System.out.println(bool?"真":"假");

对以上代码进行反编译,得到一下代码:

    Integer a=1;
    System.out.println(a.intValue()==1?"等于":"不等于");
    Boolean bool=false;
    System.out.println(bool.booleanValue()?"真":"假");

可以看到,包装类与基本数据类型进行比较运算,是先将包装类进行拆箱成基本数据类型,然后进行比较的。

场景三:包装类型的运算

有没有想过,当我们对 Integer 对象进行四则运算的时候,是如何进行的呢?看以下代码:

    Integer i=10;
    Integer j=20;
    System.out.println(i+j);

反编译代码如下:

    Integer i=10;
    Integer j=20;
    System.out.println(i.intValue()+j.intValue());

我们发现,两个包装类型之间的运算,会被自动拆箱成基本类型进行。

08-09 10:40