1. 程式人生 > >色即是空,空即是色---java有關null的幾件小事

色即是空,空即是色---java有關null的幾件小事

故事背景

---摩訶般若波羅蜜多心經:

觀自在菩薩,行深般若波羅蜜多時,照見五蘊皆空,度一切苦厄。舍利子,色不異空,空不異色;色即是空,空即是色。受想行識,亦復如是。舍利子,是諸法空相,不生不滅,不垢不淨,不增不減。是故空中無色,無受想行識,無眼耳鼻舌身意,無色聲香味觸法,無眼界,乃至無意識界,無無明,亦無無明盡,乃至無老死,亦無老死盡。無苦寂滅道,無智亦無得。以無所得故,菩提薩埵。依般若波羅蜜多故,心無掛礙,無掛礙故,無有恐怖。遠離顛倒夢想,究竟涅磐,三世諸佛,依般若波羅蜜多故,得阿耨多羅三藐三菩提。故知般若波羅蜜多是大神咒,是大明咒, 是無上咒,是無等等咒,能除一切苦,真實不虛。故說般若波羅蜜多咒,即說咒曰:揭諦揭諦,波羅揭諦,波羅僧揭諦,菩提娑婆訶。

 上面的經文總是讓我容易冷靜下來,可是java中的null總是讓我有點不知所措,下面讓我們看看吧!

java中的空null

我們先看幾段程式碼吧

1.例一:null的物件性

public class NullTest {
    public static void greet() {
        System.out.println("Hello world!");
    }
    public static void main(String[] args) {
        ((NullTest) null).greet();
    }
}

上面的程式看起來似乎應該丟擲NullPointerExceptioin 異常,因為其main 方法

是在常量null 上呼叫greet 方法,而你是不可以在null 上呼叫方法的,對嗎?

其實編譯和執行都沒有問題。執行結果為:

Hello world!

2.例二:null的初始化

    public static void main(String[] args) {
        String str=null;
        Integer in=null;
        Double dou=null;
        
        String str1=(String)null;
        Integer in1=(Integer)null;
        Double dou1=(Double)null;
        
        int in2=null;
        int in3=(int)null;
    }

 

發現null可以初始化引用型別,也可以轉換為任意的引用型別。但不能給基本型別賦值,或者轉換為基本型別。

3.例三:null的相等性

    public static void main(String[] args) {
        System.out.println(null==null);
        System.out.println(null!=null);        
        System.out.println(Double.NaN==Double.NaN);
        System.out.println(Double.NaN!=Double.NaN);
    }

結果該是什麼呢?

true

false

false

true

4.例四:null不是引用型別

    public static void main(String[] args) {
        Integer in=null;
        if(in instanceof Integer) {
            System.out.println("null is integer");
        }else {
            System.out.println("null is not integer");
        }
    }

你猜會打印出什麼?

 

結果是:

null is not integer

5.例5:不可傳遞

    public static void main(String[] args) {
        Integer i=null;
        int k=i;
        System.out.println(k);
    }

報錯:

Exception in thread "main" java.lang.NullPointerException

NullTest.main(NullTest.java:6)

6.例6:null的陣列

    public static void main(String[] args) {
        String[] arr1={"abc","123",null,"sky"};
        boolean flag=false;
        for (String s1 : arr1) {
        if(s1.equals("sky")) {
            flag=true;
            break;
        }
        }
        System.out.println(flag);
    }

執行時報錯

Exception in thread "main" java.lang.NullPointerException

at NullTest.main(NullTest.java:8)

修改成:

    public static void main(String[] args) {
        String[] arr1={"abc","123",null,"sky"};
        boolean flag=false;
        for (String s1 : arr1) {
        if(s1.equals("sky")) {
            flag=true;
            break;
        }
        }
        System.out.println(flag);
    }

就沒有問題了。

追根到底

JSL3.10.7定義了null

The null type has one value, the null reference, represented by the null literal null, which is formed from ASCII characters.

JSL4.1做了補充:

1.There is also a special null type, the type of the expression null (§3.10.7, §15.8.1), which has no name.

Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type.

2. The null reference is the only possible value of an expression of null type.

3.The null reference can always be assigned or cast to any reference type (§5.2, §5.3, §5.5).

4.In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.

參考資料

【1】https://baike.baidu.com/item/%E8%89%B2%E5%8D%B3%E6%98%AF%E7%A9%BA/6210?fr=aladdin

【2】https://docs.oracle.com/javase/specs/jls/se12/html/jls-4.html#jls-4.1

【3】https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10.7

【4】java