一道面試題的回顧

前言

辭職休息了一個月,去了一次泰國,也瘋夠了。于是回來專心找工作。陸續去了一些公司參與面試,做了一些筆試題。有一道筆試題,我做錯了。出乎我自己的意外。于是記錄以吸取教訓。

問題描敘

String s = null;
System.out.print("s="+s);

程序執行的結果是什么?是否會報錯?

我的回答(錯誤)

考慮s為null, 字符串連接的時候,我認為 會調用s的toString() 方法。這樣肯定出現空指針異常。
于是我寫出答案:

  • 程序可以編譯,但是運行時報異常。空指針異常。

正確答案

s=null

這真是讓我很懵逼。居然可以執行。而且還是null 。

解決思路

這個問題可以拆分為三個小問題。

第一個問題

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

結果輸出為 null ,這里為何輸出null .問題出在 pring函數上。定位該函數的源碼,其中有這樣的一段。

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

很粗暴的判斷。jdk的簡單處理,有點讓人失望。

第二個問題。

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

結果輸出是null. 查看函數源碼

public void print(Object obj) {
        write(String.valueOf(obj));
    }

繼續

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

一切真相大白。

第三個問題。
就是我們的面試題目,這里也是相同的原因嗎?
由于 + 是基本運算符,我們無法直接查看源碼,了解其執行的邏輯。
這個只能去查詢資料。最終的結論是 jvm 會對 + 進行優化。其執行邏輯如下:

String s = "a" + "b";
//等價于
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b");
String s = sb.toString();

因此 我們只需要去查看 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;
    }
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;
    }

結果很明顯。字符串執行 + 時,如果字符串為Null 最終添加的是 null 字符串。

總結

  • print函數對null的處理。

    • String 對象:直接判斷是否為 null,如果為 null 給 null 對象賦值為"null"。
    • 非 String 對象:通過調用String.valueOf方法,如果是 null 對象,就返回"null",否則調用對象的toString方法。
  • 字符串相加( +) 對null的處理

    • jvm會將+ 優化為 StringBuilder來處理。如果為null 則添加 "null"

以上2點,最終的結果是

打印一個 null 對象而不會拋出異常

至于為何要如此,不知道jdk的作者是怎么想的。

參考

感謝 http://blog.xiaohansong.com/2016/03/13/null-in-java-string/

其他類似面試題

類似這類的面試題還有。例如

Integer a = 12; 
Integer b = 12; 
System.out.println(a == b);
Integer a = new Integer(12); 
Integer b = new Integer(12); 
System.out.println(a == b);
Integer a = 212; 
Integer b = 212; 
System.out.println(a == b);
Integer a = 212; 
int b = 212; 
System.out.println(a == b);

以上分別打印什么? 能正確回答的估計寥寥無幾。

答案與分析http://m.blog.csdn.net/csummm4/article/details/20659363

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,738評論 18 399
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,832評論 0 11
  • 豆富小僧 今天給大家推薦一部日本動畫電影《豆富小僧》,是一個溫馨的故事,無聊的時候可以看一看。 江戶時代,百鬼夜行...
    向日葵永遠向著太陽閱讀 1,488評論 2 2
  • 北渚初曦耀,南山半日凸。 天寒孤客隱,夜盡千舟出。
    恒風閱讀 253評論 0 0
  • 設計海報并非只是將素材拼接在一起,更重要的是整個畫面的空間感搭建和光影氣氛,一張簡約大氣的海報背后是需要在...
    打豆豆閱讀 505評論 0 6