2011-09-10 12 views
11

के रूप में शून्य संदर्भ प्रिंट क्यों करता है, यहां o.toString() एनपीई फेंकता है लेकिन ओ 1, नहीं। क्यूं कर?प्रिंट संदर्भ में "शून्य"

public class RefTest { 
    public static void main(String[] args) { 
     Object o = null; 
     Object o1 = null; 
     System.out.println(o.toString()); //throws NPE 
     System.out.print(o1); // does not throw NPE 
    } 
} 
+6

यह [सभी दस्तावेज में] (http://download.oracle.com/javase/6/docs/api/java/io/PrintStream.html#print%28java.lang.Object%29) है। –

उत्तर

25

यह आपको बाइटकोड दिखाने में मदद कर सकता है। अपने वर्ग के निम्नलिखित javap उत्पादन पर एक नज़र डालें:

> javap -classpath target\test-classes -c RefTest 

Compiled from "RefTest.java" 
public class RefTest extends java.lang.Object{ 
public RefTest(); 
    Code: 
    0: aload_0 
    1: invokespecial #8; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: aconst_null 
    1: astore_1 
    2: aconst_null 
    3: astore_2 
    4: getstatic  #17; //Field java/lang/System.out:Ljava/io/PrintStream; 
    7: aload_1 
    8: invokevirtual #23; //Method java/lang/Object.toString:()Ljava/lang/String; 
    11: invokevirtual #27; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    14: getstatic  #17; //Field java/lang/System.out:Ljava/io/PrintStream; 
    17: aload_2 
    18: invokevirtual #33; //Method java/io/PrintStream.print:(Ljava/lang/Object;)V 
    21: return 

} 

बस मुख्य विधि को देखते हुए, आप ब्याज की तर्ज देख सकते हैं, जहां Code है 8 और 33.

कोड 8 बाईटकोड से पता चलता आप o.toString() पर कॉल करने के लिए। यहां onull है और इसलिए null पर विधि आमंत्रण पर कोई भी प्रयास NullPointerException में परिणाम देता है।

कोड 18 ऑब्जेक्ट को PrintStream.print() विधि के पैरामीटर के रूप में पारित किया गया दिखाता है। इस विधि के लिए स्रोत कोड को देखते हुए आपको बताएंगे कि क्यों इस एनपीई में नहीं परिणाम करता है:

public void print(Object obj) { 
    write(String.valueOf(obj)); 
} 

और String.valueOf()null रों के साथ ऐसा कर देगा:

public static String valueOf(Object obj) { 
    return (obj == null) ? "null" : obj.toString(); 
} 

तो तुम वहाँ देख सकते हैं वहां एक परीक्षण है जो null से संबंधित है, और एक एनपीई को रोकता है।

+0

ग्रेट उत्तर, धन्यवाद। – abc

+1

आपका स्वागत है। मैं अक्सर 'जावप' आउटपुट को देखकर काफी अंतर्दृष्टिपूर्ण हो सकता हूं। विशेष रूप से जब AspectJ और अन्य कोड बुनाई प्रौद्योगिकियों जैसी चीजों का उपयोग करते हैं - बस यह देखने के लिए कि उन्होंने मेरे कोड में क्या किया है! –

+0

कोड को देखने की कोई आवश्यकता नहीं है। यह सब दस्तावेज में है। 'प्रिंटस्ट्रीम :: println' कहता है कि यह' String.valueOf' कहता है, जो स्पष्ट रूप से कहता है: "यदि तर्क शून्य है, तो एक स्ट्रिंग" शून्य "के बराबर होती है, अन्यथा, obj.toString() का मान वापस आ जाता है।" – njzk2

5

क्योंकि print(Object) रूपांतरण के लिए String.valueOf(Object) का उपयोग करता है यह (एक तरफ: रूपांतरण println(Object) के बाद के रूप में यद्यपि print(String) बुलाया गया था कैसा व्यवहार करेंगे, print(Object) प्रभावी रूप से write(int) उपयोग करता है)। String.valueOf(Object) एनपीई को o.toString() की तरह फेंक नहीं देता है और इसके बजाय शून्य पैरामीटर के लिए "null" लौटने के लिए परिभाषित किया गया है।

5
System.out.println(o.toString()) 

o.toString() यह println को पार करने से पहले, एक अशक्त वस्तु भिन्नता की कोशिश कर रही है कि यह एक स्ट्रिंग के लिए कनवर्ट करने के लिए।

System.out.print(o1); 

print बुलाया जा रहा है print(Object) संस्करण है, जो अपने आप में जांच करते हुए कि वस्तु आगे बढ़ने से पहले रिक्त नहीं है है।

संबंधित मुद्दे