基本类型之自动拆装箱

自动拆装箱

基本数据类型

基本类型,又可以称为内置类型,在Java中,基本类型是不同于类(Class)的特殊类型,也是我们在编程过程中使用最频繁的类型。

关于基本数据类型的详细介绍:基础(二):基本数据类型

基本类型的优点

Java中,我们可以使用new关键字创建新对象,新创建的对象存储在堆(heap)中,我们通过栈(stack)中的引用来使用对应的对象。所以,就对象本身来说是非常消耗资源的。基本类型是我们在编程过程中使用最为频繁的类型,比如intboolean等,如果我们每次在使用的时候都通过new关键字去创建新的对象,就会显得格外的笨重。所以基本数据类型也就应运而生,这种数据的变量不需要通过new关键字进行创建,它们不会在堆(heap)上进行创建,而是直接在(stack)内存中存储,所以会更加的高效

包装类型

Java中的基本类型并不是面向对象的,所以在实际使用的过程中非常的不方便,为了解决这个问题,Java为每个基本数据类型都提供了对应的类进行表示,这样与基本数据类型相对应的类称为包装类(Wrapper Class)。

所有的包装类都在java.lang包中,基本类型与包装类的对应关系如下:

基本数据类型包装类
byteByte
booleanBoolean
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble

基本类型所对应的包装类不需要死记硬背,从表中我们可以看到,除了int、char之外的其他基本数据类型的包装类名都是其首字母大写,所以我们只需要记住char和int这两个特殊的即可,即Character,Integer

为什么需要包装类

前面的基本类型的优点中提到,Java中为了提高效率提供了八种基本数据类型,那为什么还需要包装类呢?上文中也提到由于基本数据类型不是面向对象的,所以在实际的使用过程中非常的不方便,比如我们在使用集合的时候,我们无法将基本数据类型的数据存放进集合的,因为集合容器要求元素必须是Object类型的。

为了让基本数据类型具有对象的特征,就出现了包装类,顾名思义,包装类即是把基本数据类型"包装"起来,使其具有对象的性质及特征,并且为其添加相应的属性和方法,便利了基本类型的操作。

拆箱与装箱

既然基本数据类型与包装类之间相互对应,那么它们之间也是可以相互转换的。

把基本数据类型转换为包装类的过程就是打包装,英语对应为boxing,翻译成中文为装箱

把包装类转换为基本数据类型的过程就是拆包装,英语对应为unboxing,翻译成中文为拆箱

Java1.5之前我们可以使用以下代码进行装箱操作:

	Integer i = new Integer(10);
自动拆箱与自动装箱

Java1.5版本中,Java提供了自动拆箱和自动装箱的功能。这里的自动即是需要我们手动进行操作的步骤可以省略掉,Java程序会自动完成这些操作。

	Integer i = 10; // 自动装箱
	int a = i; 		// 自动拆箱
实现原理
/**
 * 自动装箱都是通过包装类的valueOf()方法来实现的
 * 自动拆箱都是通过包装类对象的xxxValue()方法实现的
 */
public class AutoBoxing {
    public static void main(String[] args) {
        Integer integer = 10; // 自动装箱, Integer.valueOf(10)
        int i = integer;      // 自动拆箱, integer.intValue()
    }
}
使用场景
场景一:将基本类型放入集合
public class AutoBoxingTest {
    public static void main(String[] args) {
        /*
         * 不会报错,这里会进行自动装箱,
         * 即list.add(Integer.valueOf(i))
         */
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i); 
        }
    }
}
场景二:基本类型与包装类比较
/**
 * 包装类与基本类型进行比较时,都是先将包装类进行拆箱成基本数据类型,然后才进行比较的
 */
public class AutoBoxingTest {
    public static void main(String[] args) {
        Integer i = 1;
        // i.intValue() == 1
        System.out.println(i == 1 ? "equal" : "not equal");
        Boolean bool = Boolean.TRUE;
        // bool.booleanValue()
        System.out.println(bool ? "true" : "false");
    }
}
场景三:包装类型的运算
public class AutoBoxingTest {
    public static void main(String[] args) {
        /*
         * 两个包装类之间的运算都会被自动拆箱为基本类型进行
         * Integer i = Integer.valueOf(10);
         * Integer j = Integer.valueOf(20);
         *
         * i + j => i.intValue() + j.intValue();
         */
        Integer i = 10, j = 20;
        System.out.println(i + j);
    }
}
场景四:三目运算符的使用
public class AutoBoxingTest {
    public static void main(String[] args) {
        /*
         * Integer i = Integer.valueOf(0);
         * 当三目运算符的操作数为包装类对象和基本数据类型时,
         * 其中的对象就会进行自动拆箱成基本数据类型进行操作
         *
         * 如果i的值为null时,就会发生NPE
         */
        boolean flag = true;
        Integer i = 0;
        int j = 1;
        int k = flag ? i : j; // flag ? i.intValue() : j
    }
}
场景五:函数参数与返回值
public class AutoBoxingTest {
    /**
     * 自动拆箱
     *
     * @param num 整型包装类对象
     * @return 整型基本类型字面量
     */
    public int getNum1(Integer num) {
        return num;
    }

    /**
     * 自动装箱
     *
     * @param num 整型基本类型字面量
     * @return 整型包装类对象
     */
    public Integer getNum2(int num) {
        return num;
    }
}
自动拆装箱与缓存
public class AutoBoxingCache {
    public static void main(String[] args) {
        /*
         * 在Java中 == 比较的是对象的引用,而equals比较的才是值
         * 按照常规套路两个比较的输出都应该是 false,但是由于Java 5
         * 在Integer的操作上引入了一个新功能来节省内存和提高性能
         * 整型对象通过使用相同的对象引用实现了缓存和重用
         *
         * 注意:
         *    1、适用于整数值范围:-128 ~ 127
         *    2、只适用于自动装箱,使用构造函数创建的对象不适用
         */
        Integer integer1 = 10, integer2 = 10;
        System.out.println(integer1 == integer2 ? "true" : "false"); // true
        Integer integer3 = 200, integer4 = 200;
        System.out.println(integer3 == integer4 ? "true" : "false"); // false
    }
}
自动拆装箱带来的问题
  • 包装对象进行数值比较时,不能简单的使用 ==,虽然-128到127之间的数字可以,但是这个范围之外的数值还是需要使用equals比较
  • 有些场景中都会进行自动拆装箱,当包装类对象为null时,那么自动拆箱时会抛出NPE(空指针异常)
  • 如果在循环中有大量的拆装箱操作,会浪费很多的资源
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值