वैरिएबल को भीतर की कक्षा में पहुँचा जाता है। अंतिम रूप देने की आवश्यकता है


116

तो शीर्षक यह सब कहता है। मुझे मेरे अंदर एक संकलन त्रुटि हो रही है onClick

यहाँ कोड है।

public class fieldsActivity extends Activity {

Button addSiteButton;
Button cancelButton;
Button signInButton;


/**
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // to create a custom title bar for activity window
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

    setContentView(R.layout.fields);
    // use custom layout title bar
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.topbar);

    Pager adapter = new Pager();
    ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
    mPager.setAdapter(adapter);
    mPager.setCurrentItem(1);



    addSiteButton = (Button) findViewById(R.id.addSiteButton);
    addSiteButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
           mPager.setCurrentItem(2, true); //Compilation error happens here.
        }


    });


    cancelButton = (Button) findViewById(R.id.cancel_button);
    signInButton = (Button) findViewById(R.id.sign_in_button);

}

1
यदि आप ग्रहण का उपयोग कर रहे हैं तो आप क्विक फिक्स देखने के लिए चुने गए त्रुटि के साथ Ctrl-1 (OS X पर Cmd-1) दबा सकते हैं जो आपको दिखाएगा कि क्या बदलने की आवश्यकता है। : अधिक यहाँ देखें depth-first.com/articles/2008/01/11/...
Intrications

जवाबों:


130

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


1
@KevinZhao वैश्विक वैरिएबल्स के फाइनल होने के बाद एक बार उन्हें आरंभिक रूप दिया गया है?
the_prole

@ मुझे पता है कि आप जावा में फाइनल का उपयोग कर सकते हैं, लेकिन मुझे यकीन नहीं है कि अगर आप एंड्रॉइड ऐप का निर्माण करते समय इसका उपयोग कर सकते हैं, तो Googling यह एक अच्छा विचार हो सकता है :-)
केविन झाओ

15
रेट्रोस्पेक्ट में, वैश्विक चर का उपयोग करना एक बुरा विचार है यदि उन्हें टाला जा सकता है, जब तक कि आप शुरुआती नहीं होते हैं, इस मामले में ग्लोबल्स के साथ आपके कार्यक्रम को अधिक जटिल बनाना अच्छा सीखने का अनुभव है। यहाँ एक अच्छा लेख बताया गया है कि वैश्विक चर एक बुरा विचार क्यों हैं।
the_prole

65

आप चर को अंतिम घोषित कर सकते हैं, या इसे एक उदाहरण (या वैश्विक) चर बना सकते हैं। यदि आप इसे अंतिम घोषित करते हैं, तो आप इसे बाद में बदल नहीं पाएंगे।

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

मैंने यहां अधिक गहराई से स्पष्टीकरण लिखा । यह भी बताता है कि उदाहरण और वैश्विक चर को अंतिम घोषित करने की आवश्यकता क्यों नहीं है।


44

त्रुटि यह सब कहती है, बदलें:

ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);

सेवा

final ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);

87
कारण: यदि दो विधियाँ एक ही स्थानीय चर को देखती हैं, तो जावा आपको शपथ लेना चाहता है कि आप इसे नहीं बदलेंगे - finalजावा में। उप-संदर्भ मापदंडों की अनुपस्थिति के साथ, यह नियम सुनिश्चित करता है कि स्थानीय लोगों को केवल उसी विधि में सौंपा जाए जो वे संबंधित हैं। इस प्रकार कोड अधिक पठनीय है।
इग्निस

@ignis मैं एक NullPointerException त्रुटि प्राप्त कर रहा हूं addSiteButton.setOnClickListener(new View.OnClickListener() {क्या आपके पास कोई विचार है कि यह क्यों आ रहा है?
PhDeOliveira

1
जब आप किसी चर पर एक विधि कहते हैं, तो @PhDOOiveive NPE को आमतौर पर फेंक दिया जाता है null। शायद, findViewById लौट रहा है null। मैं अधिक नहीं कह सकता, एक Android प्रोग्रामर नहीं; मैं आपको एक अलग प्रश्न खोलने की सलाह देता हूं। निश्चित रूप से, इसका आंतरिक वर्गों, अंतिम, एट सिमिलिया से कोई लेना-देना नहीं है
इग्निस

25

यहाँ एक मजेदार जवाब है।

आप एक अंतिम एक-तत्व ऐरे की घोषणा कर सकते हैं और उन सभी ऐरे के तत्वों को बदल सकते हैं, जो आप चाहते हैं। मुझे यकीन है कि यह बहुत ही कारण है कि इस संकलक नियम को पहले स्थान पर लागू किया गया था, लेकिन यह तब आसान है जब आप आज के समय के अनुसार काम करते हैं।

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

final int[] tapCount = {0};

addSiteButton.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
       tapCount[0]++;
    }

});

उपरोक्त मामले में आप संदर्भित ऑब्जेक्ट को नहीं बदल रहे हैं, लेकिन सरणी के अंदर सामग्री को बदल रहे हैं। लिंक की अच्छी व्याख्या है।
अबिलाश

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

4

जैसा कि @ वीगर ने कहा, आप इसे बना सकते हैं finalताकि चर का उपयोग आंतरिक कक्षा में किया जा सके।

final ViewPager pager = (ViewPager) findViewById(R.id.fieldspager);

मैंने इसे pagerबजाय बुलाया mPagerक्योंकि आप इसे onCreateविधि में एक स्थानीय चर के रूप में उपयोग कर रहे हैं । mउपसर्ग cusomarily वर्ग सदस्य चर के लिए आरक्षित है (यानी चर कि कक्षा की शुरुआत में घोषित कर दिया और सभी वर्ग के तरीकों के लिए उपलब्ध हैं कर रहे हैं)।

यदि आपको वास्तव में एक वर्ग सदस्य चर की आवश्यकता है, तो यह अंतिम बनाने के लिए काम नहीं करता है क्योंकि आप findViewByIdइसका मूल्य निर्धारित करने के लिए उपयोग नहीं कर सकते हैं onCreate। इसका समाधान एक अनाम आंतरिक वर्ग का उपयोग नहीं करना है। इस तरह mPagerचर को अंतिम घोषित करने की आवश्यकता नहीं होती है और इसे पूरे कक्षा में उपयोग किया जा सकता है।

public class MainActivity extends AppCompatActivity {

    private ViewPager mPager;
    private Button mButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // ...

        mPager = (ViewPager) findViewById(R.id.fieldspager);

        // ...

        mButton.setOnClickListener(myButtonClickHandler);
    }


    View.OnClickListener myButtonClickHandler = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mPager.setCurrentItem(2, true);
        }
    };
}

0
    public class ConfigureActivity extends Activity {

        EditText etOne;
        EditText etTwo;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_configure);

            Button btnConfigure = findViewById(R.id.btnConfigure1);   
            btnConfigure.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            configure();
                        }
                    });
    }

    public  void configure(){
            String one = etOne.getText().toString();
            String two = etTwo.getText().toString();
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.