JavaRush /Java Blog /Random-TW /Java 中關於 NULL 的 9 件事
Sdu
等級 17

Java 中關於 NULL 的 9 件事

在 Random-TW 群組發布
Javanull齊頭並進。幾乎沒有一個 Java 程式設計師沒有遇到“空指標異常”,這是一個悲傷的事實。就連「null」概念的發明者也稱其為自己價值數十億美元的錯誤,那麼為什麼 Java 支援它呢?null 已經存在很長時間了,我猜 Java 的創建者知道它產生的問題比它解決的問題還要多,所以為什麼他們仍然忍受它。這更讓我驚訝,因為 Java 的哲學是簡化事物,這就是為什麼他們不再搞指針、運算子重載和多重繼承,但為什麼是 null?關於 Java 中 NULL 的 9 件事 - 1好吧,我真的不知道這個問題的答案,但我所知道的是,無論 Java 程式設計師和開源社群對 null 有多少批評,我們都必須忍受它。與其後悔,不如多了解一些,並確保我們正確使用 null。

為什麼要學習 Java 中的 null ?

因為如果你不注意 null,你可以肯定 Java 會讓你遭受可怕的痛苦java.lang.NullPointerException,你會學到教訓,但你會走上一條艱難的道路。編寫抗崩潰程式碼是一門藝術,您的團隊、客戶和用戶都會欣賞它。根據我的經驗,主要原因之一NullPointerException是缺乏對 Java 中 null 的了解。你們中的許多人已經熟悉 null,其餘的人將能夠了解有關 null 關鍵字的一些新舊知識。讓我們回顧或學習 Java 中 null 的一些重要知識。

Java中什麼是null

正如我所說,null 是 Java 中一個非常非常重要的概念。它最初被發明是為了指示某些東西的缺失,例如使用者、資源或其他任何東西的缺失,但一直讓許多 Java 程式設計師感到困惑null pointer exception。在本教程中,我們將了解有關 Java 中 null 關鍵字的基本事實,並學習一些避免問題並盡量null pointer exceptions減少 null 檢查的技巧。
  1. 首先,null 是 Java 中的一個關鍵字,就像public,staticfinal。大小寫敏感,不能將 null 寫成 Null 或 NULL,編譯器將無法辨識並拋出錯誤。

    Object obj = NULL; // Not Ok
    Object obj1 = null //Ok

    通常,從其他程式語言轉過來的程式設計師會遇到這個問題,但當使用現代 IDE 時,這個問題就變得微不足道了。如今,Eclipse 或 NetBeans 等 IDE 可以在您鍵入時修復此錯誤,但在記事本、Vim 和 Emacs 時代,這是一個常見問題,可能會佔用大量寶貴時間。

  2. Так же, How каждый примитив имеет meaning по умолчанию, например, у int это 0, у boolean это false, null это meaning по умолчанию любых ссылочных типов, проще говоря, для всех an objectов. Так же, How при создании логической переменной ее meaning по умолчанию равно false, так и любые ссылочные переменные в Java по умолчанию будут равны null. Это истинно для всех типов переменных: переменной-члена or локальной переменной, переменной экземпляра or статической переменной, кроме того, компилятор будет ругаться, если Вы используете локальную переменную не проинициализировав ее.

    private static Object myObj;
    public static void main(String args[]){
        System.out.println("What is value of myObjc : " + myObj);
    }
    What is value of myObjc : null

    Это истинно How для статических, так и для не статических an objectов, How Вы можете видеть здесь, я сделал myObj статической ссылкой, так что я могу использовать ее непосредственно в методе main, который является статическим методом и не позволяет обращаться к не статическим переменным изнутри.

  3. Несмотря на распространенное заблуждение, null это не an object (Object) и ни тип. Это просто специальное meaning, которое может быть назначено любому ссылочному типу, и Вы можете привести null к любому типу, How показано ниже:

    String str = null; // null can be assigned to String
    Integer itr = null; // you can assign null to Integer also
    Double dbl = null; // null can also be assigned to Double
    String myStr = (String) null; // null can be type cast to String
    Integer myItr = (Integer) null; // it can also be type casted to Integer
    Double myDbl = (Double) null; // yes it's possible, no error

    Как Вы можете видеть, приведение null к любому ссылочному типу пройдет успешно How во время компиляции, так и во время выполнения программы. В отличии от того, что многие из Вас возможно подумали, это не приведет к выбрасыванию NullPointerException.

  4. null может быть назначен только ссылочному типу, Вы не можете назначить null примитивной переменной вроде int, double, float or boolean. Компилятор выразит Вам свое недовольство если Вы сделаете How показано ниже:

    int i = null; // type mismatch : cannot convert from null to int
    short s = null; // type mismatch : cannot convert from null to short
    byte b = null: // type mismatch : cannot convert from null to byte
    double d = null; //type mismatch : cannot convert from null to double
    
    Integer itr = null; // this is ok
    int j = itr; // this is also ok, but NullPointerException at runtime

    Как Вы можете видеть, когда мы непосредственно присваиваем null примитиву, то получаем ошибку процесса компиляции, но, если присвоить null an objectу класса-обертки, а затем присвоить этот an object соответствующему примитивному типу, компилятор не отреагирует, но мы будем вознаграждены null pointer exception во время выполнения. Это происходит из-за авто упаковки (autoboxing) в Java, и мы еще встретимся с ним в следующем пункте.

  5. Любой класс-обертка со meaningм null будет выбрасывать java.lang.NullPointerException когда Java распакует(unbox) его в примитивную переменную. Некоторые программисты делают ошибку допуская, что авто упаковка(autoboxing) позаботится о конвертации null в meaning по умолчанию для соответствующего примитивного типа, например, 0 для int, false для boolean и т.д., но это не верно, в чем можно убедиться ниже:

    Integer iAmNull = null;
    int i = iAmNull; // Remember - No Compilation Error

    Но, когда Вы запустите данный фрагмент codeа, в консоли Вы увидите

    Exception in thread "main" java.lang.NullPointerException

    Это часто происходит при работе с HashMap и Integer key. Выполнение codeа, показанного ниже прервется, How только Вы его запустите.

    import java.util.HashMap;
    import java.util.Map;
    /**
    * An example of Autoboxing and NullPointerExcpetion
    *
    * @author WINDOWS 8
    */
    public class Test {
        public static void main(String args[]) throws InterruptedException {
            Map numberAndCount = new HashMap<>();
            int[] numbers = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};
            for(int i : numbers){
                int count = numberAndCount.get(i);
                numberAndCount.put(i, count++); // NullPointerException here
            }
        }
    }

    Output: Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:25)

    這段程式碼看起來非常簡單而且無害。您只需計算一個數字在陣列中出現的次數,這是尋找重複項的經典技巧。開發人員取得先前計數的數量,將其加一並將其插回 中Map。他可能認為自動裝箱會處理Integer到 的轉換int,就像調用該方法時所做的那樣put(),但他忘記了,如果尚未計算數字,該方法get()將返回HashMapnull,而不是零,因為默認值is Integer 這是null,而不是0,null pointer exception當嘗試將 Integer 轉換為變數時,自動裝箱將會拋出例外int

  6. instanceof如果將任何值為 null 的參考變數或 null 本身指定為參數,則該運算子將傳回 false。例子:

    Integer iAmNull = null;
    if(iAmNull instanceof Integer){
        System.out.println("iAmNull is instance of Integer");
    }else{
        System.out.println("iAmNull is NOT an instance of Integer");
    }

    Output : iAmNull is NOT an instance of Integer

    這是該運算符的一個重要屬性instanceof,使其對於測試類型轉換很有用。

  7. 您知道不能對空引用變數調用非靜態方法,它會調用NullPointerException,但您可能不知道可以對空引用變數調用靜態方法。因為 靜態方法使用靜態綁定,它們不會丟棄NullPointerException。這是一個例子:

    public class Testing {
        public static void main(String args[]){
            Testing myObject = null;
            myObject.iAmStaticMethod();
            myObject.iAmNonStaticMethod();
        }
        private static void iAmStaticMethod(){
            System.out.println("I am static method, can be called by null reference");
        }
        private void iAmNonStaticMethod(){
            System.out.println("I am NON static method, don't date to call me by null");
        }
    }

    Output: I am static method, can be called by null reference
    Exception in thread "main" java.lang.NullPointerException
    at Testing.main(Testing.java:11)
  8. 您可以將 null 作為參數傳遞給接受任何參考類型的方法,例如:

    public void print(Object obj)

    可以這樣稱呼

    print(null)

    從編譯器的角度來看,這是正常的,但後續行為完全取決於方法。null 安全方法不會拋出異常NullPointerException,只會優雅地退出。如果業務邏輯允許,建議編寫空安全方法。

  9. 您可以使用==(等於)和!=(不等於)運算子來比較 null,但不能將其與其他算術或邏輯運算子(例如,<小於)或>(大於)一起使用。與 SQL 不同,Javanull == null將傳回 true,如下所示:

    public class Test {
    	public static void main(String args[]) throws InterruptedException {
    		String abc = null;
    		String cde = null;
    		if(abc == cde){
    			System.out.println("null == null is true in Java");
    		}
    		if(null != null){
    			System.out.println("null != null is false in Java");
    		}
    		// classical null check
    		if(abc == null){
    			// do something
    		}
    		// not ok, compile time error
    		if(abc > null){
    
    		}
    	}
    }

    Output:
    null == null is true in Java
這就是 Java 中 null 的全部內容。透過獲得一些 Java 程式設計經驗並使用簡單的技巧來避免NullPointerException,您可以使您的程式碼安全。因為 null 可以被視為空值或未初始化的值,這通常會造成混亂,這就是為什麼在輸入 null 值時記錄方法的行為很重要。永遠記住,null 是引用變數的預設值,而且您不能在 Java 中使用 null 引用來呼叫實例方法或存取實例變數。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION