2010-03-02 15 views
9

जावा में, जब भी एक आंतरिक वर्ग उदाहरण बनाया जाता है, यह बाहरी वर्ग के उदाहरण से जुड़ा होता है। जिज्ञासा से बाहर, क्या आंतरिक कक्षा को बाहरी कक्षा के दूसरे उदाहरण के साथ जोड़ना संभव है?जावा में एक आंतरिक कक्षा के बाहरी वर्ग उदाहरण को बदलने के लिए संभव है?

+0

भविष्य में अप्रत्याशित जावा प्रतियोगिताओं में इसकी संभावित क्षमता के अलावा, क्या बात है? आप जानते हैं कि यदि आप एक आंतरिक वर्ग चाहते हैं जिसे उसके माता-पिता से अलग किया जा सकता है तो आप इसे स्थिर घोषित कर सकते हैं, है ना? –

+0

मुझे यह समस्या आकर्षक लगता है। क्या किसी को पता है कि जेएलएस में यह निर्दिष्ट किया गया है कि बाहरी वर्ग के सूचक को कैसे नाम दिया गया है? प्रयोग के माध्यम से मुझे लगता है कि यह '$ 0'' लगता है, जितना आवश्यक हो उतना '$' द्वारा जोड़ा गया (संभवतः कोई नहीं)। क्या यह वास्तव में निर्दिष्ट है? – polygenelubricants

+0

ठीक है मैंने अभी पाया है कि एक द्वितीय स्तर की आंतरिक कक्षा इसके बजाय '$ 1'' का उपयोग करती है। चित्त आकर्षण करनेवाला! – polygenelubricants

उत्तर

6

हाँ, यह संभव है: क्योंकि क्षेत्र enclosing उदाहरण की ओर इशारा करते final है। विचार अन्यथा final पॉइंटर को बाहरी उदाहरण में प्रतिबिंब का उपयोग करके सेट करना है (जिसे सफल होने की गारंटी नहीं है)।

import java.lang.reflect.*; 

public class Me { 
    final String name; 

    Me(String name) { 
     this.name = name; 
    } 

    class InnerMe {  
     String whoAreYou() { 
      return name; 
     } 
    } 

    InnerMe innerSelf() { 
     return new InnerMe(); 
    } 

    public static void main(String args[]) throws Exception { 
     final Me me = new Me("Just the old me!"); 
     final InnerMe innerMe = me.innerSelf(); 
     System.out.println(innerMe.whoAreYou()); // "Just the old me!" 
     Field outerThis = innerMe.getClass().getDeclaredFields()[0]; 
     outerThis.setAccessible(true); 
     outerThis.set(innerMe, new Me("New and improved me!")); 
     System.out.println(innerMe.whoAreYou()); // "New and improved me!" 
    } 

} 

यहाँ महत्वपूर्ण हिस्सा outerThis.setAccessible(true); है - एक SecurityManager एक नीति है कि सफल होने से इस पर प्रतिबंध लगाता है को लागू कर सकते हैं।

4

आपको प्रतिबिंब का उपयोग करने में सक्षम होना चाहिए।

बस भीतरी वर्ग (getClass().getDeclaredFields()) के सभी क्षेत्रों के लिए और देखने के जो क्षेत्र जनक रखती है, तो इसे बदल (field.set(innerInstance, newParent) उपयोग करने से पहले कि आप क्षेत्र सुलभ बनाना चाहिए -। setAccessible(true))

के बाद से क्षेत्र के लिए प्रकट होता final हो, आप इसे देखने के लिए this article पर एक नज़र डालें।

उसने कहा, आपको यह बिल्कुल करने की आवश्यकता नहीं है - यह वास्तविक लाभ के लिए एक डबल बदसूरत हैक होगा।

public class Outer { 
    public class Inner {} 
} 
... 
Outer o = new Outer(); 
Outer.Inner i = o.new Inner(); 

हालांकि, यह (setAccessible(true) के बिना) संभव नहीं है बाहरी वर्ग के अन्य उदाहरण के साथ आंतरिक वर्ग के मौजूदा उदाहरण संबद्ध करने के लिए:

5

आप इन्स्टेन्शियशन समय के बारे में बात कर रहे हैं, तो संभव निम्न सिंटैक्स का उपयोग कर है, हालांकि यह मेरे लिए एक बहुत बुरा विचार की तरह लगता है

javap Outer$Inner 

Compiled from "Outer.java" 
public class Outer$Inner extends java.lang.Object{ 
    final Outer this$0; 
    public Outer$Inner(Outer); 
} 
+0

(+1) 'अंतिम' के साथ अच्छी जगह। 'O.new इनर()' के लिए – Bozho

+0

+1 - मैंने आज एक नया वाक्यविन्यास सीखा। –

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