2011-12-21 23 views
9
public class JavaPuzzler { 

    public static void main(String[] args) { 
    JavaPuzzler javaPuzzler = null; 
    System.out.println(javaPuzzler.get()); 
    } 

    private static String get(){ 
     return "i am a java puzzler"; 
    } 
} 

आप सोच सकते हैं कि यह NullPointerException क्योंकि मुख्य विधि invokes स्थानीय चर जो आरंभ नहीं हो जाता शून्य पर पर() विधि मिल फेंक चाहिए, और आप अशक्त पर एक विधि को लागू नहीं कर सकते।मैं एक शून्य वस्तु पर एक विधि कैसे कॉल करने में सक्षम हूँ?

लेकिन अगर आप इस कार्यक्रम चलाने के लिए, आपको लगता है कि यह प्रिंट "मैं एक जावा पहेली हूँ" देखेंगे।

किसी को भी मुझे जवाब दे सकते हैं। अग्रिम धन्यवाद।

+2

मुझे लगता है कि आपके प्रिंट स्टेटमेंट में जावाजीज़लर.get() पूंजी जे – Nik

+0

@ निकुनज प्रश्न के साथ बिल्कुल सही है, शब्द में कोई गलती नहीं है। – Nik88

+0

कृपया मेरा उत्तर जांचें! – Nik

उत्तर

6

अपने कोड नमूने में, get() एक स्थिर सदस्य है जो किसी वर्ग के लिए नहीं है, उदाहरण के लिए नहीं। विधि को आमंत्रित करने के लिए आपको एक उदाहरण की आवश्यकता नहीं है।

public static String get() // belongs globally to class, no instance required 
public String get() // belongs to instance 
+0

ऐसा लगता है कि यह गलत है कि यह एक स्थिर विधि (हालांकि 'शून्य') आवृत्ति चर पर कॉल करता है। दिलचस्प है, यद्यपि। –

+1

@ एंड्रयू मार्शल: यदि आप ग्रहण में कोड आज़माते हैं, तो इसे स्वचालित रूप से class.call() से बदल दिया जाएगा example.call() – Nik

1

आपकी विधि स्थिर है। तो इसे केवल एक स्थिर तरीके से बुलाया जा सकता है।

तो भले ही आप javaPuzzler.get() के रूप में यह लगा रहे हैं, वास्तविक कॉल JavaPuzzler.get() और इस प्रकार मुद्रण किया जाएगा !!

3

get विधि स्थैतिक है, जिसका अर्थ है कि javaPuzzler में वास्तविक संदर्भ उस कॉल में अनदेखा किया जाता है, केवल चर के प्रकार का उपयोग किया जाता है।

1

आप एक स्थिर methode बुला रहे हैं, तो आप एक उदाहरण की जरूरत है इसे कहते हैं न, thats क्यों यह काम करता है।

1

अगर हम शून्य वस्तु का उपयोग कर एक विधि से कॉल करके यह NullPointerException जब तक विधि स्थिर नहीं है फेंक देते हैं।

तो विधि स्थिर है यह चलेंगे।

अधिक संदर्भ

4

क्योंकि विधि स्थिर है और आप एक उदाहरण संदर्भ हालांकि, उदाहरण के आवश्यक नहीं है यह के लिए HERE पढ़ें। जावा भाषा विशिष्टता बताती है कि क्यों section 8.4.3.2:

स्थैतिक घोषित एक विधि को क्लास विधि कहा जाता है। एक वर्ग विधि हमेशा किसी विशेष वस्तु के संदर्भ के बिना बुलाया जाता है।

इसका मतलब यह है कि अगर javaPuzzler उदाहरण रिक्त है कि यह कोई फर्क नहीं पड़ता - विधि वर्ग, नहीं एक उदाहरण के लिए "अंतर्गत आता है"।

1

की तरह हर किसी को यहाँ का उल्लेख है, यह काम करता है क्योंकि get() एक स्थिर तरीका है। यहां एक तरीका है कि आप इसके बारे में सोच सकते हैं:

जब आप जावा में किसी वर्ग को परिभाषित करते हैं, तो आप जो अनिवार्य रूप से कर रहे हैं वह उस डेटा को परिभाषित कर रहा है जो किसी ऑब्जेक्ट को पकड़ लेगा, और उस डेटा पर चलने वाली विधियों का एक सेट। अब जबकि आपके पास हजारों और हजारों वस्तुएं हो सकती हैं, लेकिन उनमें से प्रत्येक के लिए सभी विधियों की प्रतियां रखने का अर्थ नहीं है। क्या होता है कि वर्ग के तरीकों आपके द्वारा निर्धारित संग्रहीत करता है, और उन्हें उद्देश्य यह है कि आप पर विधि कॉल की गुंजाइश में निष्पादित करता है। यदि आप इन विधियों को एक प्रारंभिक ऑब्जेक्ट पर कॉल करने का प्रयास करते हैं, तो ऑब्जेक्ट अभी भी मौजूद है और विधि अभी भी मौजूद है, लेकिन इसमें काम करने के दायरे के लिए कोई मान्य नहीं है, इस प्रकार आपको NullPointerException दे रहा है।

इस नियम का अपवाद स्थिर विधियां है, जो विधियों की आवश्यकता नहीं है - वे ऑब्जेक्ट-विशिष्ट डेटा का संदर्भ नहीं लेते हैं। यही कारण है कि वे इस बात के बावजूद दौड़ सकते हैं कि ऑब्जेक्ट प्रारंभ किया गया है या नहीं।

बस याद रखें कि वस्तुओं में उनकी विधियों की प्रतियां नहीं हैं ... विधियों को केवल ऑब्जेक्ट के डेटा के दायरे में बुलाया जाता है। तो आप अभी भी शून्य (अनियमित) ऑब्जेक्ट्स के तरीकों तक पहुंच सकते हैं, लेकिन गैर स्थैतिक तरीकों पर काम करने के लिए कोई डेटा नहीं है।

0

कंपाइलर आवृत्ति कॉल को स्वचालित रूप से क्लास कॉल में बदल देता है।

... 
public static main([Ljava/lang/String;)V 
    L0 
    LINENUMBER 8 L0 
    ACONST_NULL 
    ASTORE 1 
    L1 
    LINENUMBER 9 L1 
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 
    INVOKESTATIC JavaPuzzler.get()Ljava/lang/String; 
    INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/String;)V 
    L2 
    LINENUMBER 11 L2 
    RETURN 
    L3 
    LOCALVARIABLE args [Ljava/lang/String; L0 L3 0 
    LOCALVARIABLE javaPuzzler LJavaPuzzler; L1 L3 1 
    MAXSTACK = 2 
    MAXLOCALS = 2 
... 
0

ऊपर कोड आपको मिल() समारोह के रूप में स्थिर दे दिया है में: आप एक decompiler है, तो आप उत्पन्न बाइट कोड में परिवर्तन देख सकते हैं। स्थिर कार्य और डेटा सदस्य किसी भी वस्तु से संबंधित नहीं हैं। वे कक्षा से संबंधित हैं। आप कक्षा के ऑब्जेक्ट का उपयोग करके स्थैतिक फ़ंक्शन को कॉल कर सकते हैं लेकिन यह एक अच्छा दृष्टिकोण नहीं है क्योंकि यह अतिरिक्त मेमोरी का उपभोग करता है।

स्थैतिक, JavaPuzzler.get()) के बाद से; आपको आउटपुट देगा और नल पॉइंटर अपवाद नहीं देगा।

यह प्राप्त() विधि गैर स्थैतिक होने पर शून्य सूचक अपवाद दिया होगा।