自动装箱与拆箱

自动装箱?

自动拆箱?

小朋友,你是否有很多问号?????

自动拆快递,自动装快递嘛

引文

今天来谈一下数据变量 == 的续集

首先我先摆出来一个面试题

         Integer i1 = 12;
         Integer i2 = 12;
         System.out.println(i1 == i2);
 
         Integer i3 = 1221;
         Integer i4 = 1221;
         System.out.println(i3 == i4);
 
         int i5 = i3;
         int i6 = i4;
         System.out.println(i5 == i6);

输出的结果是什么?

答案:

 true
 false
 true

what??

上篇的字符串关于 == 的我都烦透了,又来!!!!

正文

Java编程范围内,对于常见的数据类型如:int,double,long等都拥有各自包装类,如:Integer,Double,Long等

包装类?

就是对于基本数据类型进行包装,俩者数据一致但又有区别.

区别如:包装类可以作为泛型参数传递等

拆装箱?

  • 装箱:将基本类型用它们对应的引用类型包装起来;

  • 拆箱:将包装类型转换为基本数据类型;

如:

 Integer i = 10;  //装箱
 int n = i;   //拆箱

查看字节码(javap  -c UnpackingTest2.class ):

 public class com.fagejiang.unpacking.UnpackingTest2 {
  public com.fagejiang.unpacking.UnpackingTest2();
    Code:
        0: aload_0
        1: invokespecial #1                 // Method java/lang/Object."<init>":()V
        4: return
 
  public static void main(java.lang.String[]);
    Code:
        0: bipush        10
        2: invokestatic  #2                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        5: astore_1
        6: aload_1
        7: invokevirtual #3                 // Method java/lang/Integer.intValue:()I
       10: istore_2
       11: return
 }
 
 

可以发现,当定义一个Integer对象时,直接赋予常数,则默认调用Integer的valueOf()方法.

当int基本数据类型接收一个Integer对象时,默认调用intValue()方法

查看valueOf()方法源码:

     public static Integer valueOf(int i) {
         // 先去 IntegerCache 缓存池里面获取 (条件: 数值在 -128到127 即 -2^7到2^7-1 )
         if (i >= IntegerCache .low && i <= IntegerCache.high)
             return IntegerCache.cache[i + (-IntegerCache.low)];
         // 反之创建一个新的Integer的对象
         return new Integer(i);
    }

查看intValue()方法源码:

     public int intValue() {
         return value;
    }

到目前为止,上面的面试题已经知晓了原理.

扩展: 像其他的基本数据类型和包装类都是相似的操作,每个包装类都会存在valueOf()以及xxxValue()方法.

编程误区和规范

当进行数据,对象判断时,一定要使用equals()方法.

扩展

有时候真的写代码写着写着就不会写了,以下的一个小问题导致我昨天下午找了2个小时的bug

 // 判断枚举类
 public enum YzdEnum {
     StockBuyInSubmitRequest,
     StockSaleOutSubmitRequest,
     StockGenInSubmitRequest,
     StockUseOutSubmitRequest,
     LicTransportReportSubmitRequest,
     ServiceStatusRequest;
 }    
 
 // 使用的switch 见下
 
     public void switchEnumTask(List<String> requests, YzdEnum yzdEnum, String fileName) {
         switch (yzdEnum) {
             case StockBuyInSubmitRequest: {
                 // 执行业务逻辑
                 requests.forEach(request -> {
                     execute(request, fileName);
                });
            }
             case StockSaleOutSubmitRequest: {
                 requests.forEach(request -> {
                     execute(request, fileName);
                });
     
            }
             case StockGenInSubmitRequest: {
                 requests.forEach(request -> {
                     execute(request, fileName);
                });
   
            }
             case StockUseOutSubmitRequest: {
                 requests.forEach(request -> {
                     execute(request, fileName);
                });
         
            }
             case LicTransportReportSubmitRequest: {
                 requests.forEach(request -> {
                     execute(request, fileName);
                });
       
            }
             case ServiceStatusRequest: {
                 requests.forEach(request -> {
                     execute(request, fileName);
                });
 
            }
        }
    }
 

出现问题:  一个request集合被多个不同的线程执行了.

MD, 结果是少了一个break

注意

在使用switch时,每个case里面都要添加break,break用来终止switch代码块.

如果不使用break,如果进入到第X个case中,那么第x个以后的case都会执行(case判断值失效)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/20578.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!