Java三目运算中隐藏的自动拆装箱

 更新时间:2018年11月12日 08:25:10   作者:by Boyizmen  
这篇文章主要介绍了Java三目运算中隐藏的自动拆装箱,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

最近修改线上bug的时候排查了一个十分隐藏的bug,直接上代码:

Integer a = null;
boolean flag = true;
Integer b = flag ? a : 0;

乍一看是没什么毛病的,但是已运行就会发现报空指针,在idea里面也会警告可能有空指针,这是什么原因呢?

直接看字节码:

0: aconst_null
1: astore_1
2: iconst_1
3: istore_2
4: iload_2
5: ifeq     15
8: aload_1
9: invokevirtual #2       // Method java/lang/Integer.intValue:()I
12: goto     16
15: iconst_0
16: invokestatic #3      // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
19: astore_3
20: getstatic   #4      // Field java/lang/System.out:Ljava/io/PrintStream;
23: aload_3
24: invokevirtual #5      // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
27: return

可以看到字节码中调用了`Integer.valueOf()`方法,因为我们代码中一个值使用的是0(基本数据类型int),编译器就会进行自动拆装箱(成int),

虽然三目运算的后面逻辑不会执行,但是隐藏的自动拆装箱会执行`Integer.valueOf()`方法,也就有了空指针异常。

为了进一步验证存在自动拆装箱,把代码修改一下:

Integer a = null;
boolean flag = true;
Integer b = flag ? a : new Integer(0);

再看字节码:

0: aconst_null
1: astore_1
2: iconst_1
3: istore_2
4: iload_2
5: ifeq     12
8: aload_1
9: goto     20
12: new      #2      // class java/lang/Integer
15: dup
16: iconst_0
17: invokespecial #3      // Method java/lang/Integer."<init>":(I)V
20: astore_3
21: getstatic   #4      // Field java/lang/System.out:Ljava/io/PrintStream;
24: aload_3
25: invokevirtual #5      // Method java/io/PrintStream.println:(Ljava/lang/Object;)V

可以看到,由于重新创建了一个`Integer`对象,并没有基本类型的存在,也就不存在自动拆装箱,修改过后的代码也就不会有问题了,但是idea的警告依旧存在。

这是一个非常隐蔽,也非常容易忽略和踩坑的一个地方,三目运算符的使用应该保证后面的值都是常量,或者统一类型,不然就会出现上面的情况。

更甚三目运算符本身提供的作用也不过是为了简化逻辑,在其中放入过多的逻辑判断也就违背了其初衷。

总结

以上所述是小编给大家介绍的Java三目运算中隐藏的自动拆装箱,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

相关文章

  • SpringCloud Feign参数问题及解决方法

    SpringCloud Feign参数问题及解决方法

    这篇文章主要介绍了SpringCloud Feign参数问题及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Java之遍历枚举值问题

    Java之遍历枚举值问题

    这篇文章主要介绍了Java之遍历枚举值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • SpringMVC源码解析之消息转换器HttpMessageConverter

    SpringMVC源码解析之消息转换器HttpMessageConverter

    本篇文章主要介绍了SpringMVC源码解析之消息转换器HttpMessageConverter ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • win11 idea shift+F6快捷键失效问题解决方案

    win11 idea shift+F6快捷键失效问题解决方案

    这篇文章主要介绍了win11 idea shift+F6快捷键失效问题,本文给大家分享最新解决方案,需要的朋友可以参考下
    2023-08-08
  • SpringBoot多环境切换的配置实现

    SpringBoot多环境切换的配置实现

    在日常的开发中,一般都会分好几种环境,本文就来介绍一下SpringBoot多环境切换的配置实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • JAVA关键字及作用详解

    JAVA关键字及作用详解

    本文主要介绍了Java关键字及作用,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 解析Spring中的静态代理和动态代理

    解析Spring中的静态代理和动态代理

    学习 Spring 的过程中,不可避免要掌握代理模式。这篇文章总结一下代理模式。顾名思义,代理,就是你委托别人帮你办事,所以代理模式也有人称作委托模式的。比如领导要做什么事,可以委托他的秘书去帮忙做,这时就可以把秘书看做领导的代理
    2021-06-06
  • Java如何执行cmd命令

    Java如何执行cmd命令

    这篇文章主要介绍了Java如何执行cmd命令问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Springboot框架整合添加redis缓存功能

    Springboot框架整合添加redis缓存功能

    缓存就是一个存储器,在技术选型中,常用 Redis 作为缓存数据库。缓存主要是在获取资源方便性能优化的关键方面。Redis 是一个高性能的 key-value 数据库,接下来通过本文给大家介绍Springboot框架整合添加redis缓存功能,感兴趣的朋友一起看看吧
    2021-11-11
  • java使用Apache工具集实现ftp文件传输代码详解

    java使用Apache工具集实现ftp文件传输代码详解

    这篇文章主要介绍了java使用Apache工具集实现ftp文件传输代码详解,分享了详细连接ftp server和上传文件,下载文件的代码,以及结果展示,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12

最新评论