Java的關鍵字null

前言:突然有一個疑問,爲什麼容器可以添加null,比如List、Set、Map。

		HashMap<String, String> map = new HashMap<>();
        map.put(null, "1");
        map.put("123", null);
        System.out.println("null:" + map.get(null));
        System.out.println("123:" + map.get("123"));

        Set<Integer> set = new HashSet<>();
        set.add(null);
        set.add(null);
        set.add(null);
        System.out.println(Arrays.toString(set.toArray()));

運行結果表示,Map可以將null作爲key或者value,Set只能存一次null。
在這裏插入圖片描述
  我目前的理解是,null可以看成一個特殊的實例化對象,但我們無法使用它的任何屬性或者方法(空指針異常),因此在很多情況下都要進行非空判斷。

關鍵字null

在Java中,null是一種特殊的引用數據類型,表示絕對意義上的空,即不存在。

        String string;
        System.out.println(string);

比如上面的代碼,由於string沒有初始化,string沒有指向任何地址,相當於不存在,編譯會報錯。
在這裏插入圖片描述
下面的代碼編譯可以通過。

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

在這裏插入圖片描述
但此時string仍然是“不存在”的,使用string的任何屬性或者方法,比如說isEmpty(),會拋出一個運行時異常NullPointerException。
在這裏插入圖片描述

1. null和""

""是一個已經實例化的對象,和null不相等,比如直接==返回false,equals也返回false。

		String string1 = null;
        String string2 = "";
        System.out.println("null == \"\":" + (string1 == string2));
        System.out.println("\"\" equal null:" + string2.equals(string1));

在這裏插入圖片描述

2. null到底屬於哪一種類型?

null可以強制轉化爲任意一種引用類型,比如8種包裝類型,示例代碼如下。

        Integer integer = (Integer) null;
        System.out.println(null instanceof Object);         //false
        System.out.println(integer instanceof Object);      //false
        System.out.println(integer);                        //null
        
        System.out.println(integer.valueOf("123"));         //123
        System.out.println(((Integer)null).valueOf("123")); //123
        System.out.println(integer instanceof Integer);     //false

        System.out.println(null == null);						//true
        System.out.println(((Integer)null) == ((Integer)null));	//true
        System.out.println(((Short)null) == ((Integer)null));	//編譯不通過,不可比較的類型

運行結果表明,null不是超類Object的一個(子)類實例,null不屬於任何一種類。
null經過了強制類型轉換後,類的靜態屬性(比如Integer.valueOf)可以正常使用,但非靜態屬性仍然會導致異常。但最後的instanceof返回爲false,表明經過轉換後的null仍然並不屬於任何一種類型
此外,同種類型的null可以比較,不同類型比較編譯報錯。

3. jvm相關命令

我找到了一個NullType接口,此外並沒有找到其它的資料了。

/**
 * Represents the null type.
 * This is the type of the expression {@code null},
 *
 * @author Joseph D. Darcy
 * @author Scott Seligman
 * @author Peter von der Ah&eacute;
 * @since 1.6
 */

public interface NullType extends ReferenceType {
}

嘗試去看看jvm是怎麼支持null的,嘗試了下面的示例代碼

public class NullDemo {
    public static void main(String[] args) {
        Integer integer = (Integer) null;
        System.out.println(null == null);
        System.out.println(((Integer) null) == ((Integer) null));
    }
}

反彙編結果如下
在這裏插入圖片描述
似乎得到了兩條相關命令,java12文檔的介紹如下,aconst_null命令的功能是將null對象引用壓入棧。ifnonnull命令則是彈出棧頂元素,當不爲null時跳轉,而對應的ifnull則是爲null時跳轉。在文檔對於aconst_null的描述中指出,jvm並沒有爲null指定一個具體的值(可能是我翻譯地不對= =)。
在這裏插入圖片描述
在這裏插入圖片描述
  目前理解,null本身代表不確定的對象,可以理解爲一個比較特殊的實例對象,但並不屬於任何一種類型。唉,花了一個晚上,似乎還是沒有弄懂null到底怎麼實現的,先挖坑日後再填吧= =

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章