成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

String拼接出現Null?你看到的分析可是錯的

開發 開發工具
String類型真是個神奇的存在,動不動就會出現一些迷惑人的錯誤。今天看到一篇文中提到當String的值為null時,進行字符串相加拼接,會出現把null當做字符串拼接的現象。

[[398920]]

本文轉載自微信公眾號「程序新視界」,作者二師兄 。轉載本文請聯系程序新視界公眾號。

前言

String類型真是個神奇的存在,動不動就會出現一些迷惑人的錯誤。今天看到一篇文中提到當String的值為null時,進行字符串相加拼接,會出現把null當做字符串拼接的現象。

比如下面這段代碼:

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

你預期的結果可能是“hello world”,但實際的結果是“nullhello world”,神奇吧。

其實這倒沒什么,實踐一下就可以看到結果。但當你好奇心作祟,在網上搜為什么時,你看到的答案可能是錯的。

我在搜索時,看到訪問量上萬的文章給出的解釋竟然錯誤的。為了排除一些誤導,特意為大家分析一下原因。

錯誤的原因分析

如果對上述問題進行搜索,你可能看到的答案是:

  1. s + " world" 等價于 s = String.valueOf(s)+"word"

然后附帶valueOf方法:

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

你信了嗎?如果信了可能真的就錯了。下面我們就來分析分析為什么錯了。

Java編譯器的優化

我們知道,當我們寫下面的代碼時Java編譯器會為我們做一些優化:

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

如何優化的?上面這段代碼經過編譯器優化之后,等價于:

  1. StringBuilder sb = new StringBuilder(); 
  2. sb.append("Hello "); 
  3. sb.append("World"); 
  4. String result = sb.toString(); 
  5. System.out.println(result); 

也就是說,加號操作會被優化基于StringBuilder的操作,而并不是上面提到的String.valueOf操作。

那么,上面為null的情況也就等價于下面的操作了:

  1. StringBuilder sb = new StringBuilder(null); 
  2. sb.append("hello"); 
  3. sb.append(" world"); 
  4. String result = sb.toString(); 
  5. System.out.println(result); 

此時,我們再看一下StringBuilder(null)這個構造方法的底層實現,最終調到它的父類AbstractStringBuilder中的append方法:

  1. public AbstractStringBuilder append(String str) { 
  2.     if (str == null
  3.         return appendNull(); 
  4.     int len = str.length(); 
  5.     ensureCapacityInternal(count + len); 
  6.     str.getChars(0, len, value, count); 
  7.     count += len; 
  8.     return this; 

對應的appendNull方法實現為:

  1. private AbstractStringBuilder appendNull() { 
  2.     int c = count
  3.     ensureCapacityInternal(c + 4); 
  4.     final char[] value = this.value; 
  5.     value[c++] = 'n'
  6.     value[c++] = 'u'
  7.     value[c++] = 'l'
  8.     value[c++] = 'l'
  9.     count = c; 
  10.     return this; 

在appendNull方法中就是將null當做字符串“null”來處理了。這也就是為什么會在拼接中出現null的原因。

字節碼追蹤

針對上述示例,如果你想看編譯器是如何處理的,可以通過javap -c 命令來查看對應字節碼:

通過字節碼可以看出,基本上與上面的分析的一致。所以說,盡信書不如無書。

拓展問題

解決了上述問題,再來看看,如果我們單純的就打印null是怎么輸出的?

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

執行上述程序,控制臺打印null,這個null是哪兒來的呢?直接看println的底層實現:

  1. public void print(String s) { 
  2.     if (s == null) { 
  3.         s = "null"
  4.     } 
  5.     write(s); 

最終調用到了print方法,如果為null,則打印null字符串。

支持,還沒有出現最初的valueOf方法,那么valueOf方法在什么場景下會用到呢?在對象為Object類型時:

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

也就是說在明確調用valueOf方法時,此時s1的值直接是null字符串。

再拓展一下,針對一些基礎類型的包裝類,比如Integer、Double等:

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

上述代碼的處理又不太一樣,println方法實現如下:

  1. public void println(Object x) { 
  2.     String s = String.valueOf(x); 
  3.     synchronized (this) { 
  4.         print(s); 
  5.         newLine(); 
  6.     } 

也就是說先對對應的Object對象調用valueOf,回到上面的示例,如果Object為null,該方法返回null字符串,后續打印機直接為null。

小結

 

字符串拼接是很常見的問題,一不小心會出現將null給拼接上的情況。而這狀況的出現又牽扯到Java編譯器的優化,是不是很有意思?而且正如最開始所述,當我們在網絡上搜索資料時也要辨證的去看待答案的準確性。

 

責任編輯:武曉燕 來源: 程序新視界
相關推薦

2018-04-04 14:41:35

前端JavaScript面試

2022-03-18 09:42:54

JavaString

2021-05-17 10:27:42

地址虛擬邏輯

2016-03-08 09:50:42

2024-03-15 09:50:00

NULLSQL優化

2018-11-14 14:27:00

iOS 12Siri蘋果

2017-02-15 20:32:42

2016-03-28 09:39:54

2011-11-22 09:17:48

程序員

2022-05-05 19:00:22

PythonPython特性

2020-08-26 14:00:37

C++string語言

2017-06-15 08:52:36

數據分析可視化軟件開發

2023-03-21 23:48:31

ChatGPT漏洞安全

2012-05-07 17:11:54

Galaxy

2017-02-10 16:39:47

戴爾商用電腦促銷

2025-01-20 15:21:25

2019-06-03 13:53:51

蘋果iOS 13MacOS 13

2015-09-15 17:44:04

桌面智真DP300華為

2019-06-18 09:28:34

iOS 13手機黑暗模式

2021-09-14 09:19:49

一號多卡手機卡號碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品性做久久久久久 | 一区二区三区四区电影视频在线观看 | 国产美女黄色片 | 日韩aⅴ在线观看 | 亚洲欧美日韩久久久 | 精品久久久久久久久久久久久久 | 国产色网 | 美女国产精品 | 免费观看成人性生生活片 | 欧美日韩黄 | 亚洲男人的天堂网站 | 自拍 亚洲 欧美 老师 丝袜 | 久久久久久免费毛片精品 | 久久99国产精一区二区三区 | 久久精品| 国产在线一区二区三区 | 欧美成人精品激情在线观看 | 日韩精品在线看 | 精品国产欧美在线 | 视频二区在线观看 | 在线欧美视频 | 日本中文字幕一区 | 欧美xxxx黑人又粗又长 | 久久精品国产一区 | 亚洲国产高清高潮精品美女 | 午夜视频在线免费观看 | 欧美男人天堂 | 欧美性a视频 | 亚洲综合小视频 | 日本不卡一区二区三区 | 国产精品国产亚洲精品看不卡15 | 国产精品高潮呻吟久久av黑人 | 国产做a爱免费视频 | 久久九九影视 | 黄色免费网址大全 | 久热爱 | 午夜精品在线 | 亚洲人成人一区二区在线观看 | 中文字幕免费 | 99亚洲精品 | 成人在线一区二区 |