自动装箱与自动拆箱

目录

 

1.自动装箱,自动拆箱


1.自动装箱,自动拆箱

     装箱就是自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。

     java的数据类型:

     

 

自动装箱:

最主要的就是Integer b=a;这行代码执行了什么?其实这就是自动装箱的过程,上面程序在执行Integer b=a;的时候调用了Integer.valueOf ( int i ) 方法,`Integer b=a; 这段代码等同于:Integer b=Integer.valueOf ( a ) 。

自动拆箱:

其实 int a=b,这段代码等价于:int a=b.intValue(),来看看inValue()方法到底是什么,下面是源码:、

        

看看相关的题目:

 

代码1好理解,a和b指向的是堆的两块不同的区域,所以他们是不相等的,输出fasle。

代码2也好理解,他是一个自动装箱的过程,会调用Integer.valueOf ( int i ) 方法,所以,他们c,d都不会创建新的对象,而是直接从常量池中拿。所以他们都是一样的,输出true.

代码3也是哥自动装箱的过程,调用Integer.valueOf ( int i )方法,判断不在缓存中拿,所以会在堆上创建新的对象,比较的时候当然是fasle.

代码4,int g=59,首先明白这个59是存储在哪里的?由于他是基本的数据类型,所以它是存在栈中的,Integer h=new Integer(59);这个会在堆中就创建一个对象存储的是59,但是由于代码执行到g==h的时候,这时一个是基本类型一个包装类型,他们相比较,h会发生自动拆箱的过程。即调用intValue()方法返回一个int类型,基本类型就是只比较数值,所以输出true。

  接下来再看:

  这个输出会是什么?


 
 
  1. public class Test4 {
  2. public static void main(String[] args) {
  3. Double i1 = 100.0;
  4. Double i2 = 100.0;
  5. Double i3 = 200.0;
  6. Double i4 = 200.0;
  7. System.out.println(i1 == i2);
  8. System.out.println(i3 == i4);
  9. }
  10. }

 其实只要看看Double的valueOf()方法的实现就知道了:

所以他会输出false,false

注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。

   Double、Float的valueOf方法的实现是类似的。

好,接下来再看一个题目:这个输出会是什么?

 

 

 首先第一个没有什么疑问,c和d都来自缓存,所以相等输出true.

 第二个e,f的输出也没什么疑问,都会创建新的对象,所以不等,输出false.

 第三个可能刚刚看的时候有点懵逼,但是仔细想想就知道答案,首先会执行的是a+b,首先a和b是包装类型,是对象,他们是不可能相加的,所以先要执行拆箱的操作将a,b拆成基本数据类型再做相加的操作,完了之后与c进行比较,c是包装类型,所以c也会自动拆箱进行比较,这儿可能有疑问就是为什么不是自动装箱成包装类型去比较,而是包装类型进行了拆箱操作呢?

   看这个例子:

   

  如果最后是装箱操作的话,输出的就是false,所以最后他不是装箱而是拆箱操作。

  所以最后输出true.

第四个的其实就是equals()方法和==的区别,equals()和==其实一样,判断的是两个对象是否相等,但是Integer对equals()方法进行了重写,他比较的就是值,他不会进行类型转换。所以执行a+b的时候依然会有一个拆箱的过程,但是指向equals的时候她会有一个装箱的过程。所以输出的是true.

第五个和第三个有点类似,都是转化为基本的数据类型,然后比较数值,所以他们数值是相等的,返回的是true.

第六个也是先拆箱,然后相加运算,但是请注意这个和上一个直接==不同,上面可以拆箱比较数值,而这个equals()方法里面是Object类型的数据,也就是说他要传一个引用类型的参数,所以a+b会装箱成Integerr类型的数据,但是g是Long类型。类型不同就比较不了了。

第七个,对于a+h,先自动触发拆箱,就变成了int类型和long类型相加,这个会触发类型晋升,结果是long类型的,然后会触发装箱过程,就变成Long了。因此比较结果是true。

 

在项目中,当我们使用对象的比较的时候一般会用到Objects类,

 

常用方法:

1.public static boolean equals(Object a,Object b):比较对象a和对象b是否相等.
  *比较2个对象是否相等,底层依赖对象重写的equals的方法,如果没有重写,则使用Object的equals()

2.public static <T> T requireNonNull(T obj):检查对象obj不为null,如果为null,则抛出空指针异常,否则返回obj本身.
  *可以判断对象是否是空对象.限制参数不能为空.

3.public static boolean nonNull(Object obj):判断对象是否为null,不为返回true,否则返回false

4.public static boolean isNull(Object obj):和nonNull()相反.
 

参考博客:

   https://www.cnblogs.com/dolphin0520/p/3780005.html

   https://blog.csdn.net/u013309870/article/details/70229983

  https://blog.csdn.net/ijwddd/article/details/80557759

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值