String拼接出现Null?你看到的分析可是错的

域名2025-11-05 09:19:53787

本文转载自微信公众号「程序新视界」,拼接作者二师兄 。出现错转载本文请联系程序新视界公众号。拼接

前言

String类型真是出现错个神奇的存在,动不动就会出现一些迷惑人的拼接错误。今天看到一篇文中提到当String的出现错值为null时,进行字符串相加拼接,拼接会出现把null当做字符串拼接的出现错现象。

比如下面这段代码:

String s = null; s = s + "hello"; System.out.println(s + " world"); 

你预期的拼接结果可能是“hello world”,但实际的出现错结果是“nullhello world”,神奇吧。拼接

其实这倒没什么,出现错实践一下就可以看到结果。拼接但当你好奇心作祟,出现错在网上搜为什么时,拼接你看到的答案可能是错的。

我在搜索时,看到访问量上万的文章给出的解释竟然错误的。为了排除一些误导,香港云服务器特意为大家分析一下原因。

错误的原因分析

如果对上述问题进行搜索,你可能看到的答案是:

s + " world" 等价于 s = String.valueOf(s)+"word"; 

然后附带valueOf方法:

public static String valueOf(Object obj) {   return (obj == null) ? "null" : obj.toString(); } 

你信了吗?如果信了可能真的就错了。下面我们就来分析分析为什么错了。

Java编译器的优化

我们知道,当我们写下面的代码时Java编译器会为我们做一些优化:

String a = "Hello "; String b = "World"; System.out.println(a + b); 

如何优化的?上面这段代码经过编译器优化之后,等价于:

StringBuilder sb = new StringBuilder(); sb.append("Hello "); sb.append("World"); String result = sb.toString(); System.out.println(result); 

也就是说,加号操作会被优化基于StringBuilder的操作,而并不是上面提到的String.valueOf操作。

那么,上面为null的情况也就等价于下面的操作了:

StringBuilder sb = new StringBuilder(null); sb.append("hello"); sb.append(" world"); String result = sb.toString(); System.out.println(result); 

此时,我们再看一下StringBuilder(null)这个构造方法的底层实现,最终调到它的父类AbstractStringBuilder中的append方法:

public AbstractStringBuilder append(String str) {     if (str == null)         return appendNull();     int len = str.length();     ensureCapacityInternal(count + len);     str.getChars(0, len, value, count);     count += len;     return this; } 

对应的appendNull方法实现为:

private AbstractStringBuilder appendNull() {     int c = count;     ensureCapacityInternal(c + 4);     final char[] value = this.value;     value[c++] = n;     value[c++] = u;     value[c++] = l;     value[c++] = l;     count = c;     return this; } 

在appendNull方法中就是将null当做字符串“null”来处理了。这也就是为什么会在拼接中出现null的亿华云计算原因。

字节码追踪

针对上述示例,如果你想看编译器是如何处理的,可以通过javap -c 命令来查看对应字节码:

通过字节码可以看出,基本上与上面的分析的一致。所以说,尽信书不如无书。

拓展问题

解决了上述问题,再来看看,如果我们单纯的就打印null是怎么输出的?

String s = null; System.out.println(s); 

执行上述程序,控制台打印null,这个null是哪儿来的呢?直接看println的底层实现:

public void print(String s) {     if (s == null) {         s = "null";     }     write(s); } 

最终调用到了print方法,如果为null,则打印null字符串。

支持,还没有出现最初的valueOf方法,那么valueOf方法在什么场景下会用到呢?在对象为Object类型时:

Object s = null; String s1 = String.valueOf(s); System.out.println(s1); 

也就是说在明确调用valueOf方法时,此时s1的值直接是null字符串。

再拓展一下,IT技术网针对一些基础类型的包装类,比如Integer、Double等:

Integer i = null; System.out.println(i); 

上述代码的处理又不太一样,println方法实现如下:

public void println(Object x) {     String s = String.valueOf(x);     synchronized (this) {         print(s);         newLine();     } } 

也就是说先对对应的Object对象调用valueOf,回到上面的示例,如果Object为null,该方法返回null字符串,后续打印机直接为null。

小结

字符串拼接是很常见的问题,一不小心会出现将null给拼接上的情况。而这状况的出现又牵扯到Java编译器的优化,是不是很有意思?而且正如最开始所述,当我们在网络上搜索资料时也要辨证的去看待答案的准确性。

本文地址:http://www.bzve.cn/news/601a65998739.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

全站热门

探究12年Macmini的性能和特点(一台经典之作,是否依然耐用可靠?)

U盘重装Win10系统教程(快速、简便的重装Win10系统方法,助您重新焕发电脑新生)

联想电脑M4900C的性能与特点(一款实用高效的商用台式电脑)

以炫龙笔记本电脑的性能与品质如何?(全面解析以炫龙笔记本电脑,值得购买吗?)

51系统安装教程(详解51系统的安装步骤与技巧)

苍蝇灭绝的影响及其关键问题(保护环境,共同消灭苍蝇的关键)

名龙堂组装电脑的优势与体验(专业定制,品质保障,顶级性能尽在名龙堂)

荣耀9天线信号强劲稳定(优秀信号接收效果带来顺畅通话和高速网络体验)

友情链接

滇ICP备2023006006号-39