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

作者:by Boyizmen 时间:2023-11-29 10:47:10 

最近修改线上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三目运算中隐藏的自动拆装箱,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

来源:https://minei.me/archives/422.html

标签:java,三目运算,拆装箱
0
投稿

猜你喜欢

  • Android进程间大数据通信LocalSocket详解

    2023-05-21 04:21:23
  • Java泛型定义与用法实例详解

    2023-11-25 11:50:28
  • java实现在线聊天系统

    2021-07-30 08:20:54
  • Java窗口精细全方位讲解

    2023-03-05 15:35:15
  • C#预定义的基础类型转换

    2023-08-13 03:14:16
  • 利用C#实现SSLSocket加密通讯的方法详解

    2023-03-01 02:23:05
  • jQuery.event.trigger()的简单解释

    2023-05-24 03:41:37
  • Android自定义视图中图片的处理

    2023-06-29 12:07:27
  • 详解Java中运算符及用法

    2023-11-29 08:17:57
  • c#使用ManagedWifi查看当前Wifi信号并选择wifi的示例

    2021-07-06 15:37:18
  • Java如何实现树的同构?

    2023-11-28 09:55:19
  • Java 从互联网上爬邮箱代码示例

    2022-02-27 16:40:57
  • Java实现简单的飞机大战游戏(控制主飞机篇)

    2023-11-14 13:52:56
  • 解决IDEA中maven导入jar包一直报错问题

    2021-12-26 11:52:22
  • Java中String、StringBuffer、StringBuilder的区别详解

    2023-03-28 00:06:50
  • Spring Cloud整合XXL-Job的示例代码

    2021-06-09 06:01:59
  • Android图片加载库Glide用法

    2023-08-11 10:12:01
  • C# winform 模拟键盘输入自动接入访问网络的实例

    2022-01-01 19:20:10
  • Android使用ContentResolver搜索手机通讯录的方法

    2021-12-28 08:33:16
  • Java 实战项目之精品养老院管理系统的实现流程

    2022-05-30 08:18:11
  • asp之家 软件编程 m.aspxhome.com