JAVA - 关于三元运算符自动拆箱导致 NPE 的探索 [原创]

本贴最后更新于 2121 天前,其中的信息可能已经时异事殊

❤️ 三元运算符会有可能导致 NPE

今天我正在摸鱼的时候,老大大大爷 ❤️ 突然给我发消息说今天该我分享知识点呀 😰 😰 ,然后我就想到之前在 HollisChuang's Blog(大佬,建议没事就去逛逛)上看到的一篇文章 《自动拆箱导致空指针异常》(不了解可以先看看这篇文章,知道的请无视。。。),里面讲解了一个关于三元运算符中发生自动拆箱导致 NPE 的知识点,我感觉还比较有意思,于是就分享给群里的小伙伴 👍 👍 。
由于之前看过,没实践过,而今天正好分享了这个知识点,所以我就准备自己试验下。
按照文章中的例子,我敲下了同样的代码:

import java.util.*; public class Test{ public static void main(String []args){ /* * 下面两条语句即需要测试的语句 */ Map<String,Boolean> map = new HashMap<String, Boolean>(); Boolean b = (map!=null ? map.get("test") : false); } }

然后编译运行,纳尼,尽然没报错。于是又准备 javap 反编译看一下,emmm 看不太懂。以下是运行结果。
JDK8.png

虽然看不懂,但是爱思考的我 ❤️ 👍 想着别人都做过测试,那么他们的测试肯定是真实的,那么出现不一致的情况多半是 jdk 版本的问题。(没有产生 NPE 的情况我是采用的 JDK8)
然后我就试了一下 JDK11 发现,在 JDK11 的情况下会发生 NPE,,在这之后又相继试了 JDK9,JDK7。发现都会出现 NPE。那么也就证明 JDK8 版本下才会出现这个问题。
以下是 JDK7 下面的运行情况。
JDK8.png
对比了这两个反编译后的指令,发现 jdk7 反编译后多了一条指令(上图红框中)。关于这条指令的作用有兴趣的可以自己查一下。
本着,要简单,直观的弄清事情的本质的原则,我又用 jad 反编译了 jdk8 和 jdk7 生成的反编译文件
反编译的 jdk7 图示:
jdk8 版本反编译查看.png
从反编译的文件中可以看出来,在 JDK7 中,三元运算符的确在第二、第三位操作数分别是基本类型和对象的时候发生了自动拆箱。而“test”因为没有在 map 中,导致
(Boolean)hashmap.get("test")) 为空,从而 (Boolean)hashmap.get("test")).booleanValue() 发生空指针异常。😰
那么这段程序在 JDK8 下面又是发生了什么呢?同样我又对 jdk8 下的 class 文件反编译,得到的结果如图示:
JDK8 版本反编译并查看.png
从反编译后的代码中可以看出,在 jdk8 的情况下,三元运算符并没有对这种情况进行自动拆箱,相反,而是进行了自动装箱。所以这就是为什么在 jdk8 版本下该代码能够顺利的编译并执行,而其他版本却报 NPE 的原因了吧。

那么,为什么 JDK8 要这样处理呢?为什么又要在之后的版本改回去呢?这之中涉及到了什么东西??我也不知道呀。。。如果你有撒好的观点,可以告知我让我也打开下另外的大门!!

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3203 引用 • 8217 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 108 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖
  • 音乐

    你听到信仰的声音了么?

    62 引用 • 512 回帖
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 367 回帖
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 49 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 776 关注
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4601 回帖 • 709 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 40 关注
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 555 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 390 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 663 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 68 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖 • 1 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 652 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 259 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • 反馈

    Communication channel for makers and users.

    120 引用 • 906 回帖 • 279 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 651 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 7 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖 • 2 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 686 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖 • 2 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    134 引用 • 1128 回帖 • 110 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 355 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 11 关注
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    59 引用 • 22 回帖 • 1 关注