2013-06-09 5 views
23

मैं सिंगलटन पैटर्न लागू करने के लिए निम्नलिखित कोड लिखा है:

public final class Test { 
    static final class TestHolder { 
     private static final Test INSTANCE = new Test(); 
    }  

    private Test() {} 

    public static Test getInstance() { 
     return TestHolder.INSTANCE; 
    } 
} 

जब मैं इस फ़ाइल संकलन, यह Test.class और टेस्ट $ TestHolder.class उत्पन्न करनी चाहिए, लेकिन यह भी टेस्ट $ 1.class उत्पन्न करता है। यह समझ में नहीं आता है। तो यह क्यों और कैसे होगा?

+0

http://c2.com/cgi/wiki?AnonymousInnerClass – sircapsalot

+3

@sircapsalot सवाल यह है कि * अज्ञात वर्ग कहां है *। –

+2

यह अपवॉट के लायक प्रश्नों का प्रकार है। –

उत्तर

25

कक्षा TestHolder को निजी निर्माता को Test में कॉल करने की आवश्यकता है। लेकिन यह निजी है, और वास्तव में किसी अन्य वर्ग से नहीं बुलाया जा सकता है। तो संकलक एक चाल निभाता है। यह Test पर एक नया गैर-निजी कन्स्ट्रक्टर जोड़ता है जो केवल इसके बारे में जानता है! वह कन्स्ट्रक्टर इस अज्ञात वर्ग Test$1 का एक (अप्रयुक्त) उदाहरण लेता है - जिसे कोई भी नहीं जानता है। तब TestHolderTest$1 का एक उदाहरण बनाता है और कहता है कि निर्माता है, जो पहुँचा जा सकता है (यह डिफ़ॉल्ट-सुरक्षित।)

आप javap -c Test (और javap -c Test\$1, और javap -c Test\$TestHolder) का उपयोग कर सकते कोड को देखने के लिए। यह वास्तव में काफी चालाक है!

+0

बाइट कोड को डीकंपलिंग करने से इस उत्तर-स्टेटिक इनरर्क्लास टेस्ट $ 1 टेस्ट नल 'उत्पन्न होता है। – Makoto

+0

महान उत्तर, चालाक कार्यान्वयन। क्या आप इसे अपने सिर के ऊपर से जानते थे? – Vulcan

+0

@ वल्कन, नहीं, मैंने नहीं किया। सोचा था कि यह एक दिलचस्प सवाल था, कोड संकलित किया, इसे 'जावप' के साथ चेक आउट किया, और समझाया कि मुझे क्या मिला। –

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