- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Java String 对 null 对象的容错处理
前言最近在读《Thinking in Java》,看到这样一段话:Primitives that are fields in a class are automatically initialized to zero, as noted in the Everything Is an Object chapter. But the object references are initialized to null, and if you try to call methods for any of them, you’ll get an exception-a runtime error. Conveniently, you can still print a null reference without throwing an exception.大意是:原生类型会被自动初始化为 0,但是对象引用会被初始化为 null,如果你尝试调用该对象的方法,就会抛出空指针异常。通常,你可以打印一个 null 对象而不会抛出异常。第一句相信大家都会容易理解,这是类型初始化的基础知识,但是第二句就让我很疑惑:为什么打印一个 null 对象不会抛出异常?带着这个疑问,我开始了解惑之旅。下面我将详细阐述我解决这个问题的思路,并且深入 JDK 源码找到问题的答案。解决问题的过程可以发现,其实这个问题有几种情况,所以我们分类讨论各种情况,看最后能不能得到答案。首先,我们把这个问题分解为三个小问题,逐一解决。第一个问题直接打印 null 的 String 对象,会得到什么结果?String s = null;System.out.print(s);运行的结果是null果然如书上说的没有抛出异常,而是打印了null。显然问题的线索在于print函数的源码中。我们找到print的源码:public void print(String s) { if (s == null) { s = null; } write(s);}看到源码才发现原来就只是加了一句判断而已,简单粗暴,可能你对 JDK 的简单实现有点失望了。放心,第一个问题只是开胃菜而已,大餐还在后面。第二个问题打印一个 null 的非 String 对象,例如说 Integer:Integer i = null;System.out.print(i);运行的结果不出意料:null我们再去看看print的源码:public void print(Object obj) { write(String.valueOf(obj));}有点不一样的了,看来秘密藏在valueOf里面。public static String valueOf(Object obj) { return (obj == null) ? null : obj.toString();}看到这里,我们终于发现了打印 null 对象不会抛出异常的秘密。print方法对 String 对象和非 String 对象分开进行处理。String 对象:直接判断是否为 null,如果为 null 给 null 对象赋值为null。非 String 对象:通过调用String.valueOf方法,如果是 null 对象,就返回null,否则调用对象的toString方法。通过上面的处理,可以保证打印 null 对象不会出错。到这里,本文就应该结束了。什么?说好的大餐呢?上面还不够塞牙缝呢。开玩笑啦。下面我们来探讨第三个问题。第三个问题(隐藏的大餐)null 对象与字符串拼接会得到什么结果?String s = null;s = s + !;System.out.print(s);结果可能你也猜到了:null!为什么呢?跟踪代码运行可以发现,这回跟print没有什么关系。但是上面的代码就调用了print函数,不是它会是谁呢?+的嫌疑最大,但是+又不是函数,我们怎么看到它的源代码?这种情况,唯一的解释就是编译器动了手脚,天网恢恢,疏而不漏,找不到源代码,我们可以去看看编译器生成的字节码。L0 LINENUMBER 27 L0 ACONST_NULL ASTORE 1L1 LINENUMBER 28 L1 NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder.init ()V ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; LDC ! INVOKEVIRTUAL java/lang/StringBuilder.append
文档评论(0)