एक स्थिर विधि के भीतर गैर-स्थिर आंतरिक वर्ग को तत्काल कैसे करें?


122

मेरे पास निम्नलिखित कोड है:

public class MyClass {

   class Inner {
     int s, e, p;
   }

   public static void main(String args[]) {
     Inner in;
   }
}

इस भाग तक कोड ठीक है, लेकिन मैं मुख्य विधि के भीतर 'इन्स्टैंटिज्म' करने में सक्षम नहीं हूं जैसे in = new Inner()यह दिखा रहा है non static field cannot be referenced in static context

मेरे पास ऐसा करने का कौन सा तरीका है? मैं अपनी Innerकक्षा को स्थिर नहीं बनाना चाहता ।


जवाबों:


201

आपके पास अन्य बाहरी वर्ग के लिए भी एक संदर्भ होना चाहिए।

Inner inner = new MyClass().new Inner();

अगर इनर स्थिर होता तो ऐसा ही होता

Inner inner = new MyClass.Inner();

53
इस जवाब ने जीवन के प्रति मेरे दृष्टिकोण को बदल दिया। आउटर.नई इनर ()? इसे कभी संभावना भी नहीं माना। O_O
एल्बेअमकीर

1
स्टैटिक इनर के लिए, क्या आप केवल इनर इनर = नया इनर () नहीं कर सकते?
कैन लू

1
@CanLu स्थिर नेस्टेड क्लास के लिए एक ऑब्जेक्ट बनाने के लिए, उपयोग करें OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass()नेस्टेड क्लासेस
लिटिल लाइटल्यू

37

एक "नियमित" आंतरिक वर्ग में एक बाहरी वर्ग उदाहरण के लिए एक छिपा हुआ (अंतर्निहित) सूचक होता है। यह संकलक को आपके द्वारा इसे टाइप किए बिना आपके लिए पॉइंटर का पीछा करने के लिए कोड उत्पन्न करने की अनुमति देता है। उदाहरण के लिए, यदि बाहरी वर्ग में कोई चर "a" है, तो आपके आंतरिक वर्ग का कोड "a = 0" कर सकता है, लेकिन संकलक छिपे हुए पॉइंटर को बनाए रखते हुए "externalPointer.a = 0" के लिए कोड उत्पन्न करेगा। कवर।

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

यदि आप अपने आंतरिक वर्ग को "स्थिर" बनाते हैं तो कोई छिपा हुआ सूचक नहीं है और आपका आंतरिक वर्ग बाहरी वर्ग के सदस्यों का संदर्भ नहीं दे सकता है। एक स्थिर आंतरिक वर्ग एक नियमित कक्षा के समान है, लेकिन इसका नाम अभिभावक के अंदर रखा गया है।

यहाँ कोड का एक स्निपेट है जो स्थिर और गैर-स्थिर आंतरिक वर्ग बनाने के लिए वाक्यविन्यास प्रदर्शित करता है:

public class MyClass {

    int a,b,c; // Some members for MyClass

    static class InnerOne {
        int s,e,p;
        void clearA() {
            //a = 0;  Can't do this ... no outer pointer
        }
    }

    class InnerTwo {
        //MyClass parentPointer;      Hidden pointer to outer instance
        void clearA() {         
            a = 0;
            //outerPointer.a = 0      The compiler generates this code
        }       
    }

    void myClassMember() {
        // The compiler knows that "this" is the outer reference to give
        // to the new "two" instance.
        InnerTwo two = new InnerTwo(); //same as this.new InnerTwo()
    }

    public static void main(String args[]) {

        MyClass outer = new MyClass();

        InnerTwo x = outer.new InnerTwo(); // Have to set the hidden pointer
        InnerOne y = new InnerOne(); // a "static" inner has no hidden pointer
        InnerOne z = new MyClass.InnerOne(); // In other classes you have to spell out the scope

    }

}

4

यदि आप new Inner()किसी विधि से बनाना चाहते हैं , तो इसे कक्षा की आवृत्ति विधि से करें MyClass:

public void main(){
  Inner inner = new Inner();
}

public static void main(String args[]){
  new MyClass().main();
}

0

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

import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JPanel;
import javax.swing.JFrame;

public class Example {
    public class InnerClass extends JPanel {
        public void paint(Graphics g) {
            g.setColor(Color.BLACK);
            g.fillRect(getX(),getY(),getWidth(),getHeight());
            g.setColor(Color.RED);
            g.fillRect(5, 20, 195, 20);
            g.setColor(Color.BLACK);
            g.drawString("This was written by an inner class.", 10, 35);
        }
    }

    public void demonstrate() {
        InnerClass sc = new InnerClass();//<---this is key
        JFrame jf = new JFrame();
        jf.add(sc);
        jf.setSize(220, 130);
        jf.setLocation(450, 450);
        jf.show();
    }

    public static void main(String[] params) {
        Example e = new Example();//<---so is this
        e.demonstrate();//<---and this is also key
    }
}

परिशिष्ट: You -can- स्थैतिक तरीकों से स्थिर आंतरिक कक्षाओं को तत्काल। इस तरह के कोड को केवल स्थिर विधियों के भीतर से गैर-स्थैतिक आंतरिक वर्गों को तत्काल करने की आवश्यकता है।
हर्बर्ट सैमुअल जेनिंग्स III
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.