गैर-स्थैतिक विधि के लिए एक स्थिर संदर्भ नहीं बना सकता


102

जावा में एक बहु-भाषा अनुप्रयोग का निर्माण। R.stringसंसाधन XML फ़ाइल से स्ट्रिंग मान सम्मिलित करते समय एक त्रुटि हो रही है :

public static final String TTT =  (String) getText(R.string.TTT);

यह त्रुटि संदेश है:

त्रुटि: गैर-स्थैतिक विधि getText (int) के संदर्भ में टाइप संदर्भ से एक स्थिर संदर्भ नहीं बना सकता है

यह कैसे होता है और मैं इसे कैसे हल कर सकता हूं?


1
'बहु भाषा अनुप्रयोग' के लिए आपको स्थिर होने की आवश्यकता क्यों है? वास्तव में समझ में नहीं आता।
xil3

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

जवाबों:


143

चूंकि getText()गैर-स्थैतिक है आप इसे स्थैतिक विधि से नहीं कह सकते।

यह समझने के लिए कि, आपको दोनों के बीच के अंतर को समझना होगा।

इंस्टेंस (नॉन-स्टैटिक) तरीके उन वस्तुओं पर काम करते हैं जो एक विशेष प्रकार (वर्ग) के होते हैं। इन्हें नए के साथ इस तरह बनाया गया है:

SomeClass myObject = new SomeClass();

एक इंस्टेंस विधि को कॉल करने के लिए, आप इसे इंस्टेंस पर कॉल करते हैं ( myObject):

myObject.getText(...)

हालाँकि एक स्टैटिक मेथड / फील्ड को सीधे टाइप पर ही कॉल किया जा सकता है , इस तरह कहें: पिछला स्टेटमेंट सही नहीं है। कोई भी स्थिर फ़ील्ड को ऑब्जेक्ट संदर्भ के साथ संदर्भित कर सकता है जैसे कि myObject.staticMethod() लेकिन यह हतोत्साहित किया जाता है क्योंकि यह स्पष्ट नहीं करता है कि वे वर्ग चर हैं।

... = SomeClass.final

और दोनों एक साथ काम नहीं कर सकते क्योंकि वे विभिन्न डेटा स्पेस (उदाहरण डेटा और क्लास डेटा) पर काम करते हैं

मुझे कोशिश करके समझाइए। इस वर्ग पर विचार करें (psuedocode):

class Test {
     string somedata = "99";
     string getText() { return somedata; } 
     static string TTT = "0";
}

अब मेरे पास निम्नलिखित उपयोग का मामला है:

Test item1 = new Test();
 item1.somedata = "200";

 Test item2 = new Test();

 Test.TTT = "1";

मान क्या हैं?

कुंआ

in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99

दूसरे शब्दों में, TTTएक डेटाम है जिसे सभी प्रकार के उदाहरणों द्वारा साझा किया जाता है। तो यह कहने का कोई मतलब नहीं है

class Test {
         string somedata = "99";
         string getText() { return somedata; } 
  static string TTT = getText(); // error there is is no somedata at this point 
}

तो सवाल यह है कि टीटीटी स्थिर क्यों है या गेटटेक्स्ट () स्थिर क्यों नहीं है?

निकालें staticऔर इसे इस त्रुटि को प्राप्त करना चाहिए - लेकिन यह समझने के बिना कि आपका प्रकार क्या है यह केवल एक त्रुटि वाला प्लास्टर है अगली त्रुटि तक। getText()गैर-स्थैतिक होने के लिए इसकी क्या आवश्यकताएं हैं ?


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

लेकिन वह मेरी बात है। आपको यह समझने की आवश्यकता है कि दोनों का उपयोग कब किया जा सकता है।
प्रीत संघ

जब मैं अपने मुख्य गतिविधि वर्ग में "कॉन्स्टेंट नोटिफिकेशन_वल्यूस = नया कॉन्स्टेंट =) जोड़ता हूं, तो यह ठीक है, लेकिन एमुलेटर में यह गतिविधि चलने पर क्रैश हो जाता है
चेन एम

12

गैर-स्थैतिक Contextविधि के मिश्रण का getText()उपयोग आपके साथ क्यों नहीं किया जा सकता है, इस स्पष्टीकरण के साथ पहले से ही कुछ अच्छे उत्तर हैं static final String

एक अच्छा सवाल पूछना है: आप ऐसा क्यों करना चाहते हैं? आप Stringअपने stringsसंसाधन से लोड करने का प्रयास कर रहे हैं , और इसके मूल्य को एक public staticक्षेत्र में आबाद कर रहे हैं । मुझे लगता है कि यह इसलिए है ताकि आपके कुछ अन्य वर्ग इसे एक्सेस कर सकें? यदि हां, तो ऐसा करने की कोई आवश्यकता नहीं है। इसके बजाय Contextअपने अन्य कक्षाओं में प्रवेश करें और context.getText(R.string.TTT)उनके भीतर से कॉल करें।

public class NonActivity {

    public static void doStuff(Context context) {
        String TTT = context.getText(R.string.TTT);
        ...
    }
}

और इसे अपने से कॉल करने के लिए Activity:

NonActivity.doStuff(this);

यह आपको Stringकिसी public staticक्षेत्र का उपयोग करने की आवश्यकता के बिना अपने संसाधन तक पहुंचने की अनुमति देगा ।


1
बहुत-बहुत धन्यवाद, मैंने आपकी सिफारिश के अनुसार सभी फाइलों को बदल दिया।
चेन एम

मैं यह करने की कोशिश कर रहा था, लेकिन एक स्ट्रिंग-सरणी के लिए, और साथ String a[] = context.getTextArray(R.array.myStringArray); ; यह, हालांकि, मुझे एक त्रुटि देता है The method getTextArray(int) is undefined for the type Context- यह अपरिभाषित क्यों होगा जबकि यह गेटटेक्स्ट के साथ काम करता है?
शुभ

1
@ शुभ ९९ केवल इसलिए क्योंकि Contextइसमें एक विधि नहीं है जिसे बुलाया गया है getTextArray, लेकिन यह है getText। शायद आप सोच रहे हैं कि Resourcesकौन हैgetTextArray
dave.c

आह, धन्यवाद! एक संसाधन के बजाय एक संदर्भ (गतिविधि से गैर-सक्रियता) में पारित किया गया, और मेरे getStringArray ने काम किया।
शुभ

9

दूसरों के लिए जो इस खोज में मिलते हैं:

मुझे अक्सर यह मिलता है जब मैं गलती से ऑब्जेक्ट नाम के बजाय क्लास नाम का उपयोग करके फ़ंक्शन को कॉल करता हूं। यह आमतौर पर होता है क्योंकि मैं उन्हें बहुत समान नाम देता हूं: पी

अर्थात:

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

यह स्पष्ट रूप से एक स्थिर विधि है। (somethings के लिए अच्छा) लेकिन मैं वास्तव में क्या करना चाहता था (ज्यादातर मामलों में)

myclass.someFunction();

यह इतनी मूर्खतापूर्ण गलती है, लेकिन हर कुछ महीनों में, मैं "माइक्लास" परिभाषाओं में लगभग 30 मिनट बर्बाद कर देता हूं ताकि यह पता चल सके कि वास्तव में क्या गलत हो रहा है।

मजेदार नोट: स्टैक ओवरफ्लो यहाँ गलती को स्पष्ट करने के लिए सिंटैक्स पर प्रकाश डालता है।


क्या आपकी आईडीई इस पर प्रकाश नहीं डालती है? मुझे लगता है कि आप इसे ऐसा करने के लिए कॉन्फ़िगर कर सकते हैं :)
Matthias Meid

2

आप या तो अपने चर को गैर स्थिर बना सकते हैं

public final String TTT =  (String) getText(R.string.TTT);

या "getText" विधि को स्थिर बनाएं (यदि संभव हो तो)


2

getText आपकी गतिविधि का एक सदस्य है, इसलिए इसे "यह" मौजूद होने पर बुलाया जाना चाहिए। आपकी गतिविधि शुरू होने से पहले जब आपका वर्ग लोड हो जाता है तो आपका स्थिर वैरिएबल आरंभिक होता है।

चूँकि आप चाहते हैं कि वैरिएबल को संसाधन स्ट्रिंग से आरंभ किया जाए तो यह स्थिर नहीं हो सकता है। यदि आप चाहते हैं कि यह स्थिर हो तो आप इसे स्ट्रिंग मूल्य के साथ आरंभ कर सकते हैं।


2

आप गैर-स्थिर विधि से स्थैतिक चर का संदर्भ नहीं दे सकते। इसे समझने के लिए, आपको स्थैतिक और गैर-स्थैतिक के बीच के अंतर को समझने की आवश्यकता है।

स्थैतिक चर वर्ग चर होते हैं, वे केवल एक ही उदाहरण के साथ वर्ग के होते हैं, केवल पहले पर बनाए जाते हैं। हर बार जब आप क्लास की कोई वस्तु बनाते हैं तो गैर-स्टैटिक वैरिएबल को इनिशियलाइज़ किया जाता है।

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


0

यह प्रश्न नया नहीं है और मौजूदा उत्तर कुछ अच्छी सैद्धांतिक पृष्ठभूमि देते हैं। मैं सिर्फ एक और व्यावहारिक जवाब जोड़ना चाहता हूं।

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

इसे हल करने के कई तरीके हैं:

  1. स्थैतिक संशोधक को हटाकर और इसे कक्षा शरीर के भीतर रखकर गतिविधि के अन्य चर (क्षेत्र) का चर या अन्य उपवर्ग का चर बनाएं;
  2. इसे स्थिर रखें और बाद के बिंदु पर इनिशियलाइज़ेशन में देरी करें (जैसे ऑनक्रिट विधि में);
  3. वास्तविक उपयोग के स्थान पर इसे स्थानीय परिवर्तनशील बनाएं।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.