Java 教程

Java 控制語句

面向物件程式設計

Java 內建類

Java 檔案處理

Java 錯誤與異常

Java 多執行緒

Java 同步

Java 網路

Java 集合

Java 介面

Java 資料結構

Java 集合演算法

高階 Java

Java 雜項

Java API 與框架

Java 類參考

Java 有用資源

Java - 空指標異常



在 Java 14 中,引入了一項名為“有幫助的NullPointerException”的新特性。當時它是一個預覽特性,後來成為了 JDK 的標準部分。此增強背後的動機是使用更多詳細資訊豐富 NullPointerException,因為傳統的 NullPointerException 僅提供了發生 NullPointerException 的檔名、方法和行號的詳細資訊。

Java 中傳統的空指標異常

在 Java 14 增強 NullPointerException 之前,以下程式碼將顯示如下所示的 NullPointerException 訊息

// Create an employee without department
Employee emp = new Employee(1,"Robert",null);

// get the name of the dept
// as name is null, this code will throw a null pointer exception
String dept = emp.getDept().getName();

如果使用此程式碼片段執行,則將產生類似的結果:

Exception in thread "main" java.lang.NullPointerException
	at com.tutorialspoint.Tester.main(Tester.java:10)

Java 中新的資訊性空指標異常

在除錯過程中,這樣的錯誤訊息沒有用。並且在多級巢狀的情況下,檢查哪個欄位為空導致問題變得更加困難。Java 14 滿足了這一需求。在這種情況下,它提供了一個選項來返回如下所示的更有幫助的訊息

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.tutorialspoint.Department.getName()" because the return value of "com.tutorialspoint.Employee.getDept()" is null
	at com.tutorialspoint.Tester.main(Tester.java:10)

在這裡我們可以看到,列印了更多資訊的訊息來幫助除錯 getDept() 為空導致的問題。為了在 Java 14 中啟用此功能,我們必須使用以下標誌執行 Java 程式碼。

-XX:+ShowCodeDetailsInExceptionMessages

現在在 Java 20 中,不再需要此標誌。

針對空物件的幫助性 NullPointerException

在此示例中,我們展示了上面學習的概念。這是一個非常有用的功能,可以除錯由空引用引起的錯誤。在這裡,我們建立了兩個類 Employee 和 Department。在 main 方法中,我們建立了 Employee 類的物件,但 department 傳遞為 null。然後我們嘗試獲取員工的部門名稱,這會導致 NullPointerException。在輸出中,我們可以看到由JVM引發的資訊性空指標異常。

示例

package com.tutorialspoint;

import java.util.List;

public class Tester {

   public static void main(String[] args) {
      // declare an employee without department
      Employee emp = new Employee(1,"Robert",null);

      // get department name of null department will
      // throw a NullPointerException
      String dept = emp.getDept().getName();
      System.out.println(dept);
   }  
}

class Employee {
   int id;
   String name;
   Department dept;

   Employee (int id, String name, Department dept){
      this.id = id;
      this.name = name;
      this.dept = dept;
   }
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public Department getDept() {
      return dept;
   }
   public void setDept(Department dept) {
      this.dept = dept;
   }
}

class Department {
   int id;
   String name;
   List<Employee> employees;
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public List<Employee> getEmployees() {
      return employees;
   }
   public void setEmployees(List<Employee> employees) {
      this.employees = employees;
   }
}

輸出

讓我們編譯並執行上述程式,這將產生以下結果:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.tutorialspoint.Department.getName()" because the return value of "com.tutorialspoint.Employee.getDept()" is null
	at com.tutorialspoint.Tester.main(Tester.java:10)

資訊性 NullPointerException - 本地空變數

類似於物件引用,區域性變數可以為 null。在 Java 14 中,如果使用空區域性變數,則 JVM 會將變數名稱列印為 <local>,如下所示

String name = null;   
System.out.println("Length: " + name.length() );

如果使用此程式碼片段執行,則將產生類似的結果:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "<local1>" is null
	at com.tutorialspoint.Tester.main(Tester.java:8)

為了列印區域性變數的名稱,我們在執行程式時必須使用以下標誌。

-g

使用此標誌會導致以下輸出。

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null
	at com.tutorialspoint.Tester.main(Tester.java:8)

從 Java 20 開始,不再需要此標誌。請參閱以下完整示例

針對空區域性變數的幫助性 NullPointerException

在此示例中,我們展示了上面學習的概念來除錯空區域性引用。在這裡,我們建立了一個名為 name 的區域性變數,並且我們嘗試獲取空字串變數的長度,這將導致 NullPointerException。在輸出中,我們可以看到 JVM 引發的資訊性空指標異常,其中包含空變數的實際名稱。

示例

package com.tutorialspoint;

public class Tester {

   public static void main(String[] args) {	   
	   String name = null;
       // accessing property of null local variable
       // will cause a NullPointerException
	   System.out.println("Length: " + name.length() );
   }  
}

輸出

讓我們編譯並執行上述程式,這將產生以下結果:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null
	at com.tutorialspoint.Tester.main(Tester.java:8)
廣告