जब आंतरिक कक्षाओं को जावा में भाषा के संस्करण 1.1 में जोड़ा गया था, तो उन्हें मूल रूप से 1.0 संगत कोड में परिवर्तन के रूप में परिभाषित किया गया था। यदि आप इस परिवर्तन का एक उदाहरण देखते हैं, मुझे लगता है कि यह बहुत स्पष्ट कर देगा कि एक आंतरिक वर्ग वास्तव में कैसे काम करता है।
इयान रॉबर्ट्स के उत्तर के कोड पर विचार करें:
public class Foo {
int val;
public Foo(int v) { val = v; }
class Bar {
public void printVal() {
System.out.println(val);
}
}
public Bar createBar() {
return new Bar();
}
}
1.0 संगत कोड में तब्दील होने पर, आंतरिक वर्ग Barकुछ इस तरह बन जाएगा:
class Foo$Bar {
private Foo this$0;
Foo$Bar(Foo outerThis) {
this.this$0 = outerThis;
}
public void printVal() {
System.out.println(this$0.val);
}
}
आंतरिक वर्ग का नाम बाहरी वर्ग के नाम के साथ उपसर्ग किया जाता है ताकि इसे अद्वितीय बनाया जा सके। एक छिपा हुआ निजी this$0सदस्य जोड़ा जाता है जो बाहरी की एक प्रति रखता हैthis । और उस सदस्य को इनिशियलाइज़ करने के लिए एक हिडन कंस्ट्रक्टर बनाया जाता है।
और यदि आप createBarविधि को देखते हैं, तो यह कुछ इस तरह से बदल जाएगा:
public Foo$Bar createBar() {
return new Foo$Bar(this);
}
तो आइए देखें कि जब आप निम्नलिखित कोड निष्पादित करते हैं तो क्या होता है।
Foo f = new Foo(5);
Foo.Bar b = f.createBar();
b.printVal();
पहले हम एक उदाहरण के लिए Fooत्वरित करते हैं और val5 (यानी f.val = 5) के लिए सदस्य को सूचित करते हैं ।
इसके बाद हम कॉल करते हैं f.createBar(), जो इंस्टेंट का उदाहरण देता है Foo$Barऔर this$0सदस्य को (यानी ) thisमें पास किए गए मूल्य को इनिशियलाइज़ करता है ।createBarb.this$0 = f
अंत में हम कॉल करते हैं b.printVal()जो प्रिंट करने की कोशिश करता b.this$0.valहै f.valजो कि 5 है।
अब वह एक आंतरिक वर्ग की नियमित तात्कालिकता थी। आइए देखें कि जब Barबाहर से तात्कालिकता होती है तो क्या होता है Foo।
Foo f = new Foo(5);
Foo.Bar b = f.new Bar();
b.printVal();
हमारे 1.0 परिवर्तन को फिर से लागू करते हुए, दूसरी पंक्ति कुछ इस तरह बन जाएगी:
Foo$Bar b = new Foo$Bar(f);
यह f.createBar()कॉल करने के लिए लगभग समान है । एक बार फिर हम एक उदाहरण की तात्कालिकता कर रहे हैं Foo$Barऔर this$0सदस्य को आरम्भ कर रहे हैं । इसलिए फिर से,b.this$0 = f।
और फिर जब आप कॉल b.printVal(), आप प्रिंट कर रहे हैं b.thi$0.valजो है f.val, जो 5 है।
याद रखने वाली महत्वपूर्ण बात यह है कि आंतरिक वर्ग में एक छिपा सदस्य thisहोता है, जो बाहरी कक्षा से एक कॉपी रखता है । जब आप बाहरी वर्ग के भीतर से एक आंतरिक वर्ग को त्वरित करते हैं, तो यह वर्तमान मूल्य के साथ प्रारंभिक रूप से आरोपित होता है this। जब आप बाहरी वर्ग के बाहर से आंतरिक वर्ग को त्वरित करते हैं, तो आप स्पष्ट रूप से newकीवर्ड पर उपसर्ग के माध्यम से बाहरी वर्ग के किस उदाहरण का उपयोग करना चाहते हैं ।