[英]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?
實際上,我們可以通過查看System的Javadoc並搜索“ 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中,如果s
為null
則將引發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.