2008-11-14 24 views
171

बहुत आम शुरुआत गलती तब होती है जब आप उस वर्ग के उदाहरण के बिना "स्थैतिक रूप से" वर्ग संपत्ति का उपयोग करने का प्रयास करते हैं। यह आपको उल्लिखित त्रुटि संदेश के साथ छोड़ देता है:"स्थैतिक संदर्भ से गैर स्थैतिक विधि का संदर्भ नहीं दिया जा सकता है" के पीछे क्या कारण है?

आप या तो गैर स्थैतिक विधि स्थिर बना सकते हैं या उस गुण का उपयोग अपनी संपत्तियों का उपयोग करने के लिए कर सकते हैं।

क्यों? मैं समाधान मांग नहीं रहा हूं। मैं जानना चाहूंगा कि इसके पीछे क्या कारण है। बहुत मूल कारण!

private java.util.List<String> someMethod(){ 
    /* Some Code */ 
    return someList;    
} 

public static void main(String[] strArgs){   
    // The following statement causes the error. You know why.. 
    java.util.List<String> someList = someMethod();   
} 

उत्तर

253

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

+3

"चूंकि आपने कोई ऑब्जेक्ट नहीं बनाया है, इसलिए गैर स्थैतिक विधि अभी तक मौजूद नहीं है।" - बहुत बहुत धन्यवाद। मुझे इसके बारे में सोचना चाहिए था। – DragonBorn

+5

विधि स्वयं मौजूद है। कहीं भी लोड कक्षा परिभाषा में। तो जवाब गलत है :) –

+28

@Vladimir, ठीक है अगर आप picky होना चाहते हैं। :) "वर्तमान संदर्भ में मौजूद नहीं है" :) –

41

विधि आप कॉल करने के लिए कोशिश कर रहे हैं एक उदाहरण स्तरीय विधि है; आपके पास कोई उदाहरण नहीं है।

static विधियां कक्षा से संबंधित हैं, गैर -static विधियां कक्षा के उदाहरणों से संबंधित हैं।

+0

"गैर-स्थैतिक विधियां कक्षा के उदाहरणों से संबंधित हैं" - उत्तर। लेकिन यह कक्षा के उदाहरण से संबंधित क्यों है? धन्यवाद। – DragonBorn

+9

@ZiG: क्योंकि आपने इसे स्थिर –

+1

चिह्नित करने के लिए कहा है, शुरुआती डेवलपर्स के लिए, मैंने यह समझने के लिए एक उदाहरण बनाया है कि @ StevenA.Lowe ऊपर क्या उल्लेख करता है। https://repl.it/repls/WavyNeighboringSpotteddolphin – supritshah1289

1

एक स्थैतिक विधि एक प्रकार के ऑब्जेक्ट से एक क्रिया से संबंधित है, जबकि गैर स्थिर विधि उस प्रकार के ऑब्जेक्ट के उदाहरण के लिए एक क्रिया से संबंधित है। आम तौर पर यह एक तरीका है जो उदाहरण के संबंध में कुछ करता है।

पूर्व:

वर्ग कार वॉश विधि है, जो एक विशेष कार धोने का संकेत होगा, जबकि एक स्थिर विधि प्रकार कार पर लागू होगा हो सकता है।

+0

सभी विधियों के दुष्प्रभाव नहीं हैं! * ए * के लिए कोई कार्रवाई नहीं होनी चाहिए, यह कुछ भी हो सकता है जो ऑब्जेक्ट आपको बताता है। – Hugo

1

यदि कोई विधि स्थैतिक नहीं है, तो "कंपाइलर" बताता है कि विधि को कक्षा में आवृत्ति-स्तर डेटा तक पहुंच की आवश्यकता है, (एक गैर स्थैतिक फ़ील्ड की तरह)। यह डेटा तब तक उपलब्ध नहीं होगा जब तक वर्ग का एक उदाहरण नहीं बनाया गया हो। इसलिए यदि आप किसी विधि को विधि से कॉल करने का प्रयास करते हैं तो संकलक एक त्रुटि फेंकता है .. यदि वास्तव में विधि कक्षा के किसी भी गैर-स्थैतिक सदस्य को संदर्भित नहीं करती है, तो विधि को स्थिर बनाएं।

Resharper, उदाहरण के लिए, बस एक गैर स्थैतिक विधि वर्ग के किसी भी स्थिर सदस्य को संदर्भित नहीं करती कि बनाने एक चेतावनी संदेश

4

जवाब अब तक क्यों वर्णन "यह पद्धति स्थिर किया जा सकता है", उत्पन्न करता है

आप अपने निर्माता के लिए एक विधि कॉल जोड़कर एक instantiable वर्ग से कोई विधि कॉल कर सकते हैं कर सकते हैं,

Object instance = new Constuctor().methodCall(); 

या

: लेकिन यहां किसी और एक कुछ आप विचार करना चाह सकते है
primitive name = new Constuctor().methodCall(); 

यह उपयोगी है कि आप केवल एक ही दायरे में एक बार एक तत्काल कक्षा के तरीके का उपयोग करना चाहते हैं। यदि आप एक स्कोप के भीतर एक तत्काल कक्षा से कई विधियों को बुला रहे हैं, तो निश्चित रूप से एक संदर्भ योग्य उदाहरण बनाएं।

10

मुझे अभी एहसास हुआ, मुझे लगता है कि लोगों को "स्थिर" की अवधारणा से बहुत जल्दी अवगत नहीं होना चाहिए।

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

+0

मुझे ऊपर बताई गई त्रुटि के साथ इस समस्या का सामना करना पड़ा है, लेकिन विभिन्न गतिविधियों में कक्षा के उदाहरण का उपयोग करने के लिए स्थिर का उपयोग करना सीखना चाहिए, इसलिए मैं इसके साथ संघर्ष कर रहा हूं। :(इतनी सारी चीजों की कोशिश कर रहा है, लेकिन काम नहीं कर रहा है। – Azurespot

2

कंपाइलर वास्तव में गैर स्थैतिक तरीकों के लिए एक तर्क जोड़ता है। यह this pointer/reference. This is also the reason why a static method can not use this जोड़ता है, क्योंकि कोई ऑब्जेक्ट नहीं है।

16

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग का सार तर्क के साथ एक साथ तर्क को समाहित कर रहा है।

इंस्टेंस विधियां तर्क हैं, उदाहरण फ़ील्ड डेटा हैं। साथ में, वे एक वस्तु बनाते हैं।

public class Foo 
{ 
    private String foo; 
    public Foo(String foo){ this.foo = foo; } 
    public getFoo(){ return this.foo; } 

    public static void main(String[] args){ 
     System.out.println(getFoo()); 
    } 
} 

उपर्युक्त प्रोग्राम चलाने का परिणाम संभवतः क्या हो सकता है?

किसी ऑब्जेक्ट के बिना, कोई आवृत्ति डेटा नहीं है, और उदाहरण विधियों को कक्षा परिभाषा के हिस्से के रूप में मौजूद होने पर, उन्हें उनके लिए डेटा प्रदान करने के लिए ऑब्जेक्ट इंस्टेंस की आवश्यकता होती है।

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

+0

सबसे अच्छा जवाब –

0

इसके पीछे कारण यह है कि सरल माता पिता वर्ग की स्टेटिक डेटा सदस्यों पहुँचा जा सकता है (केवल अगर वे ओवरराइड नहीं कर रहे हैं), लेकिन उदाहरण (गैर स्थिर) के लिए डेटा के सदस्यों या तरीकों हम उनके संदर्भ की आवश्यकता है और इसलिए वे कर सकते हैं केवल एक वस्तु के माध्यम से कहा जाता है।

10

मुझे लगता है कि उनका कहना है कि जावा भाषा के नियमों से जावा के बराबर सम्मिलित करता है लायक है "इस।" जब यह नोटिस करता है कि आप एक स्पष्ट उदाहरण के बिना उदाहरण विधियों या उदाहरण फ़ील्ड तक पहुंच रहे हैं। बेशक, संकलक जानता है कि यह केवल एक उदाहरण विधि है, जो एक "इस" चर है, स्थिर तरीकों नहीं है के रूप में भीतर से ऐसा कर सकते हैं।

जिसका मतलब है कि जब आप एक उदाहरण विधि निम्नलिखित में हैं बराबर हैं:

instanceMethod(); 
this.instanceMethod(); 

और ये भी बराबर हैं: "। इस"

... = instanceField; 
... = this.instanceField; 

संकलक प्रभावी रूप से डालने है जब आप एक विशिष्ट उदाहरण की आपूर्ति नहीं करते हैं।

यह (यमक इरादा) "जादू की मदद" संकलक novices को भ्रमित कर सकते द्वारा की बिट: इसका मतलब है कि उदाहरण के कॉल और स्थिर कॉल कभी कभी एक ही वाक्य रचना है, जबकि वास्तविकता में विभिन्न प्रकार और अंतर्निहित तंत्र की कॉल कर रहे हैं दिखाई देते हैं।

उदाहरण विधि कॉल कभी कभी एक विधि मंगलाचरण या क्योंकि बहुरूपता समर्थन आभासी तरीकों में से व्यवहार के प्रेषण के रूप में भेजा जाता है; भेजने व्यवहार के लिए कि क्या आप उपयोग का सुस्पष्ट वस्तु दृष्टान्त लिखा या संकलक एक डाला परवाह किए बिना होता है "इस।"।

स्थिर विधि कॉल तंत्र एक गैर OOP भाषा में एक समारोह कॉल की तरह सरल, है।

व्यक्तिगत रूप से, मुझे लगता है कि त्रुटि संदेश भ्रामक है, यह पढ़ सकता है "गैर स्थैतिक विधि एक स्थिर संदर्भ से संदर्भित नहीं किया जा सकता एक स्पष्ट वस्तु दृष्टान्त निर्दिष्ट किए बिना"।


संकलक इस बारे में शिकायत कर रहा है कि यह केवल मानक "यह" नहीं डाल सकता है। क्योंकि यह उदाहरण विधियों के भीतर करता है, क्योंकि यह कोड एक स्थिर विधि के भीतर है; हालांकि, शायद लेखक इस आमंत्रण — के लिए ब्याज के उदाहरण की आपूर्ति करना भूल गए हैं, एक उदाहरण संभवतः स्थैतिक विधि को पैरामीटर के रूप में प्रदान किया गया है, या इस स्थिर विधि के भीतर बनाया गया है।

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

2

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

0

तो आप एक बहुत ही मूल कारण पूछ रहे हैं?

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

मेरी अंग्रेजी के लिए खेद है! मैं लैटिन हूँ!

0

एक गैर स्थैतिक विधि वस्तु पर निर्भर है। ऑब्जेक्ट बनने के बाद प्रोग्राम द्वारा इसे पहचाना जाता है।

किसी ऑब्जेक्ट के निर्माण से पहले भी स्थिर विधियों को बुलाया जा सकता है। तुलनात्मक तरीके या संचालन करने के लिए स्टेटिक विधियां बहुत अच्छी हैं जो वास्तविक वस्तुओं पर निर्भर नहीं हैं जिनके साथ आप काम करने की योजना बना रहे हैं।

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

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