【学习Day11】什么是自动装箱和自动拆箱,什么时候下应该避免自动拆装箱?

在这里插入图片描述

一、什么是自动拆箱和自动装箱?

装箱:
装箱操作就是把基础数据类型自动转换成引用类型,比如定义一个数值类型
Integer num = 1它自动把int类型的数字转换为对应的引用类型,这就是装箱操作。

拆箱:
拆箱操作就是把引用类型转换为对应的基础类型,比如Integer num = 20这个num变量赋值给int sumber = num 这就是拆箱操作。

二、常见的自动拆装箱操作类型?

装箱类型拆箱类型
Integerint
Charchar
Floatfloat
Doubledouble
Longlong
Shortshort
Bytebyte
Booleanboolean

以上就是自动拆装箱对应的类型,拆装箱操作针对于Java的八种基本数据类型,基本数据类型就是拆箱类型,而装箱类型就是引用类型也成为封装类。

三、基本数据类型和封装类的区别?

类型基础数据类型包装类
默认值不同字符串为‘’ 数字为0null
存储位置
传递数据值传递引用传递
创建变量直接给变量赋值创建对象在赋值
比较==equals

数据传递分为值传递引用传递,他们的区别就是在使用的过程值传递直接使用这个的对象的值,而引用传递传递的是存在在堆中的内存地址,在根据这个内存地址去拿到对应的值。

四、基本数据类型和封装类优缺点?

4.1、基础数据类型

优点:

  1. 读取速度快(因为存储在栈中)
  2. 没有拆箱操作,提高性能

缺点:

  1. 功能少,只能做简单的操作

4.2、封装类

优点:

  1. 由于是对象,它有丰富的方法,可以做复杂的功能
  2. 封装得到好处,在于隐藏实现的得到细节,更安全

缺点:

  1. 读取速度会比基础数据类型快(因为存储在堆中,以及要进行拆箱操作

五、基本数据类型和封装类适用场景

基础数据类型:
操作简单的场景,比如一个类需要两个int类型的变量来做一个sum的操作,就可以使用基础数据类型,在比如用一个boolean类型的一个变量做一个判断就完全可以用基础数据类型,用引用类型也没问题,但是没必要,那样只会浪费资源。

封装类:
复杂操作的场景,以及值有可能为Null的情况。

  1. 场景1:比如定义一个Integer类型的变量,用它作为一个方法的返回值,这个方法经过一些列的操作,最后得到一个Integer类型的数据,我们并不知道它最后返回一个什么东西,有可能是数字,也有可能啥也没有,如果用int类型来接收Null,就出出现空指针异常,这时候就得用包装类来接收。
  2. 场景2:在比如我想要得到Integer这个类型的最大值,这时用基础类型是不行的因为它没有任何的方法,它只能存储数据,就得用封装类调用Integer.MAX_VALUE来实现。

六、可能出现的问题以及什么时候避免自动拆装箱

以上简单的了解了自动拆装箱是什么,它们有什么区别,那么现在来了解一下在自动拆装箱的时候会出现什么问题

问题1: NullPointerException异常,上面场景下提到了,在一系列操作过后,有可能会出现Null这中情况一定要用封装类,不可让他自动拆箱

问题2: 通过以上它们的区别可知,在比较数值的时候有所不同, == 和 equals都可以比较值,但是它们又不同的地方,==只能比较-128 到 127 之间的数字,超出这个范围就要用equals,原因后续补充
问题3: 比如在一个循环中定义一个int类型,而在下面调用其他方法返回值为Integer 把这个值赋给int这个拆箱操作就会很浪费资源,在这种情况最好保持类型一致。

七、总结

根据以上内容分析,基础数据类型和封装类都有各自的好处,根据实际的需要来选择,需要注意的是自动拆装箱NPM异常的问题,在使用的过程中要谨慎。

后续

八、Integer 与128的故事

上面已说明基础类型和封装类的区别,其中有一条在比较值的时候不同,下面就来详细说说他们的不同

  • 为什么Integer a = 128, Integer b = 128 用双等比较不相等?
    在这里插入图片描述
    为什么用==比较127的时候返回true,128就返回false了呢?这里面有一个大大大大得到坑。原因是Integer自在的缓存模式惹的祸,定义Integer类型它自动进行了装箱操作,通过Integer的valueOf方法实现,让我们来看看源码
    在这里插入图片描述
    在我们通过Integer a = 1的时候它自动通过valueOf(int i)这个方法来实现,而这个方法里面有IntegerCache的字样,问题就出在这里,让我们来看看,首先它做了一个判断,其中有两个属性low和high,这个两个东西是啥 继续来看
    在这里插入图片描述
    那两个属性是IntegerCache静态类中的两个属性,并且第一个是-128,high它的值是在静态代码块中赋的默认给了127,啊那就知道了那个判断的意思了就是我们赋值的时候如果值在-128到127之间他就会放在缓存里面,如果超过这个范围就会重新new Integer(),new出来的东西肯定是堆里面了。看到这里就知道为啥128不相等,-128到127之间的值都是在一个地方,而超过范围它是两个对象了啊,那肯定不相等啊。这就是原因

  • 为什么会有Integer缓存

因为我们常见的基本数据类型中,使用包装类包装数值时会创建大量对象,如果没有缓存的话,会有大量的包装类被创建,占用内存,降低效率。选择最常用的数值范围设置缓存机制,就可以优化这一现象。

  • 自定义缓存的大小

只可以设置最大值,不可以设置最小值,在运行的时候添加一下参数
-XX:AutoBoxCacheMax=最大值

在这里插入图片描述
其运行结果
在这里插入图片描述

  • 其他数据类型缓存

在这里插入图片描述

来源 https://blog.csdn.net/LNF568611/article/details/123599649

完结

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值