簡體   English   中英

JVM 如何知道何時拋出 NullPointerException

[英]How does the JVM know when to throw a NullPointerException

Java 虛擬機如何知道何時拋出 NullPointerException? 它是否在我對對象調用的每個方法之前檢查該對象是否為空以檢查它是否必須拋出 NullPointerException? 如果是這樣,這不是真的很慢嗎?

JVM 可以使用兩種方法來“檢測”空值。

  • JVM 可以在使用引用之前顯式測試它的值。 這代表了一種開銷,但 JIT 編譯器可以優化掉一些空測試。 例如:

    1. this的方法調用不能給出 NPE。
    2. 如果p不是 volatile 並且你這樣寫:

       if (p != null) { p.something(); }

      然后, p.something()的隱含空檢查。

    3. 如果p不是 volatile 並且你這樣寫:

       p.something(); p.somethingElse();

      然后不需要第二個隱含空檢查。

    還值得注意的是,空測試對具有深度管道的 CPU 的性能影響為零。 這將取決於本地化內存訪問模式,以及編譯器/硬件是否能夠安排測試指令與(比如)內存獲取或存儲重疊。

  • JVM 可以使用虛擬內存硬件來實現空檢查。 JVM 將其虛擬地址空間中的頁面 0 映射到不可讀 + 不可寫的頁面。 由於null表示為零,當 Java 代碼嘗試取消引用null這將嘗試訪問不可尋址的頁面,並導致操作系統向 JVM 傳遞“段錯誤”信號。 JVM 的段錯誤信號處理程序可以捕獲這個,找出代碼在哪里執行,並在適當線程的堆棧上創建和拋出 NPE。

    這很復雜而且相當昂貴。 但是,只要 NPE 在應用程序中出現得足夠少,費用就無關緊要。

NULLPointerException 基本上是一個運行時異常,即 JVM 期望在您執行任何操作時引用一個實際對象。

為了更好地理解這一點,您需要知道在 java 中是如何創建和引用對象的。語法如下: myClass o = new myClass();

在這種情況下,將在堆空間中創建一個對象,其中 o 作為對該對象的引用,即 o 基本上指向該對象。 在運行時,JVM 確定 o 指向的實際對象並使用它來執行操作。

因此,假設您有一個方法 doSomething() 作為上述 myClass 定義的實例方法,並且您像這樣調用它 o.doSomething(),因此 JVM 將找到實際對象並調用此方法。

但是如果你設置 o = null; 那么 o 不指向 myclass 的實際對象,即 o 不指向任何內容。 所以現在在 o.doSomething 的執行過程中,JVM 發現 o 沒有指向任何東西,並在這種情況下拋出運行時異常 NULLPointerException。

它並不慢,因為它是 JVM 的設計方式,它對運行時發生的實際引用對象進行操作,如果您沒有在程序中正確處理 NULL 檢查並且 JVM 拋出 NULLpointerException,那么您的程序將崩潰並且 jvm 終止.

有關更多信息,請參閱 java 文檔: http : //docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM