簡體   English   中英

系統對象可能會引發空指針異常的情況是什么?

[英]what are the scenarios where System object might throw a null pointer exception?

我正在准備面試,當我經歷空指針異常時,我突然意識到每個對象都可以以某種方式拋出空指針異常,但是我似乎無法想象某些對象(例如System,Out等)會拋出NullPointerException 誰能提到這種情況? 謝謝!

例如: System.out.println(s.get(name));

首先, System不是對象。 這是一個靜態方法的類。 其次, out是該類的靜態字段,(最初)是對標准輸出PrintStream的引用。 您可以使用System.setOut(PrintStream)將該PrintStream更改為您自己的。

最后,如果您做了

System.setOut(null);
System.out.println("42"); // because out is now a null reference 

您將獲得NullPointerException

當然,您還可以找到System的方法,該方法也會引發NullPointerException

當您嘗試取消引用null對象引用時,JVM會拋出大多數這些NullPointerException

您不會取消引用課程。

只有可執行代碼可以拋出NPE,例如方法,構造函數或初始化程序。 -馬可

並非每個對象都能夠引發NullPointerException。 通常最好嘗試編寫不能的類!

public class ClassThatCannotNPE {

     public int getOne() {
         return 1;
     }
}

您可以使用上述類做兩件事,即運行其構造函數並調用getOne()。 NPE都不可以。

我們必須謹慎地通過說“某物”引發異常來定義我們的意思。 此代碼將在第2行拋出NPE:

Date d = null;
System.setProperty("now",d.toString());

但這不是系統或系統代碼引發異常的示例。 上面的代碼等效於:

Date d = null;
String temp = d.toString();
System.setProperty(temp);

在System.setProperty()有機會運行之前,這還會在第2行上拋出NPE。 執行順序與前面的示例完全相同。

關於什么:

System.out.print(null);

這將引發一個NPE。 但是再一次,不是系統拋出的代碼。 它等效於:

PrintStream temp = System.out;
temp.print(null);

NPE發生在第2行-它不涉及系統,也不涉及系統。


System是一個類,而不是對象。 它沒有構造函數,因此無法實例化。

但是,它有很多靜態方法。 是否有可能使其中任何一個拋出NullPointerException?

實際上,我們可以通過查看SystemJavadoc並搜索“ NullPointerException”來快速找到。 許多對象的第一個匹配項是在System.arraycopy()中

如果dest為null,則拋出NullPointerException。

所以你有它:

System.arrayCopy(null,0,null,0,0);

...將導致System類中的某些代碼拋出NPE。


實際上,我們可以查看System實際源代碼,並查看它在哪里拋出NullPointerExceptions。

488       public static native void arraycopy(Object src,  int  srcPos,
489                                           Object dest, int destPos,
490                                           int length);

哦。 arraycopy是本機的-意味着實際的實現是JRE中的一些C代碼。 但是我們還能找到什么呢?

825       private static void checkKey(String key) {
826           if (key == null) {
827               throw new NullPointerException("key can't be null");
828           }
...

777       public static String setProperty(String key, String value) {
778           checkKey(key);
...

因此,使系統代碼拋出NPE的另一種方法是:

System.setProperty(null,"value");

null對象進行的操作將拋出NullPointerException 在示例s.get(name) e中,如果snull則將引發NullPointerException 由於System是一個class ,因此靜態引用將不會為null。 查看源代碼,您可以看到out是靜態的和final ,最終使用以下命令初始化。

setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));

通常,由於它是final這意味着它不會為null ,也不能設為null 但是, public static void setOut(PrintStream out)調用本機函數private static native void setOut0(PrintStream out) ,實現中的VM可以在其中創建空引用。

它是否將拋出NullPointerException取決於方法的實現。 具體來說, println(String)在對傳入的變量進行操作之前將進行空檢查。

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
    }

因此,在這種情況下,只要正確初始化PrintStream ,方法本身就不應引發NullPointerException ,對於System來說,是正確的。

我希望這有助於回答您的問題。 如果沒有,請在評論中清楚說明您要尋找的內容。

包裝器類可以拋出NPE。盡管Java提供了自動裝箱功能,但默認情況下它們不像原始數據類型那樣被初始化。

Integer r;
if(r>1)

暫無
暫無

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

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