2013-05-27 5 views
18

यह एक बहुत ही व्यापक प्रसार enum सिंगलटन कोड है। लेकिन मैं उलझन में हूँ के बाद मैं 'Inside the Java Virtual Machine' के अध्याय 7 पढ़ें - एक प्रकार का जीवनकाल:एंटम के माध्यम से सिंगलटन आलसी शुरू हुआ है? ने कहा कि यह एक आलसी आरंभीकरण है</p> <pre><code>public enum enumClazz{ INSTANCE enumClazz(){ //do something } } </code></pre> <p>और स्थानों की एक गुच्छा:

जावा आभासी मशीन विनिर्देश कार्यान्वयन वर्ग और इंटरफ़ेस लोडिंग के समय में लचीलापन और जोड़ने, लेकिन सख्ती से देता है प्रारंभिक समय के समय को परिभाषित करता है। सभी कार्यान्वयन को अपने पहले सक्रिय उपयोग पर प्रत्येक कक्षा या इंटरफ़ेस को प्रारंभ करना होगा।

  • एक वर्ग का एक नया उदाहरण बन जाता है (एक नई शिक्षा का निष्पादन bytecodes में, वैकल्पिक रूप से, निहित निर्माण, प्रतिबिंब, क्लोनिंग, या अक्रमांकन के माध्यम से।।): निम्नलिखित छह स्थितियों के रूप में सक्रिय उपयोग करता है अर्हता
  • एक स्थिर विधि एक वर्ग द्वारा घोषित के आह्वान (bytecodes में, एक invokestatic शिक्षा का निष्पादन)
  • उपयोग या एक स्थिर क्षेत्र क्लास अथवा अंतरफलक द्वारा घोषित का काम, स्थिर क्षेत्रों है कि अंतिम कर रहे हैं के अलावा और द्वारा संकलित एक संकलन-समय निरंतर अभिव्यक्ति (बाइटकोड में रों, एक getstatic या putstatic अनुदेश) के निष्पादन
  • ऐसे वर्ग कक्षा में तरीकों के रूप में या java.lang.reflect में कक्षाओं में जावा एपीआई में कुछ चिंतनशील तरीकों, के आह्वान पैकेज
  • आरंभीकरण जब एक जावा आभासी मशीन
शुरू होता है एक वर्ग का एक उपवर्ग के (एक वर्ग के प्रारंभ में अपनी सुपर क्लास की पूर्व प्रारंभ की आवश्यकता है।)
  • प्रारंभिक वर्ग के रूप में एक वर्ग के पद पर नियुक्ति (मुख्य() < विधि के साथ)
  • बोल्ड शैली के साथ तीसरा बिंदु स्पष्ट करता है कि यदि क्षेत्र static final है, तो फ़ील्ड का प्रारंभिक संकलन समय पर हुआ है। इसी प्रकार, INSTANCEenumClazz में public static final के बराबर है और तीसरे बिंदु का अनुपालन करता है।

    क्या मेरी समझ गलत है अगर कोई मुझे सही कर सकता है?

    उत्तर

    25

    enum उदाहरण फ़ील्ड "संकलन-समय निरंतर अभिव्यक्ति द्वारा प्रारंभ किया गया" है। वे नहीं हो सकते हैं, क्योंकि only String and primitive types are possible types for a compile-time constant expression

    इसका मतलब है कि कक्षा शुरू की जाएगी जब INSTANCE पहली बार एक्सेस किया गया है (जो वास्तव में वांछित प्रभाव है)।

    बड़े अक्षरों में अपवाद ऊपर मौजूद है, क्योंकि उन स्थिरांक (static final क्षेत्रों एक संकलन समय निरंतर अभिव्यक्ति के साथ प्रारंभ) को प्रभावी ढंग संकलन के दौरान inlined किया जाएगा: इस उदाहरण में

    class A { 
        public static final String FOO = "foo"; 
    
        static { 
        System.out.println("initializing A"); 
        } 
    } 
    
    class B { 
        public static void main(String[] args) { 
        System.out.println(A.FOO); 
        } 
    } 
    

    निष्पादित वर्ग B होगा A प्रारंभ करें (और प्रिंट "प्रारंभिक ए" प्रिंट करें)। और यदि आप B के लिए जेनरेट किए गए बाइटकोड को देखते हैं तो आपको श्रेणी "foo" और no वर्ग A के संदर्भ में एक स्ट्रिंग अक्षरशः दिखाई देगा।

    3

    बोल्ड शैली के साथ तीसरा बिंदु को स्पष्ट करता है, तो क्षेत्र 'स्थिर अंतिम' है कि मैदान की initialzation complie समय

    ऐसा नहीं है पर हुआ है - यह केवल करने के लिए "स्थिर लागू होता है क्षेत्रों है कि अंतिम और एक संकलन समय से प्रारंभ निरंतर अभिव्यक्ति हैं ":

    static final String = "abc"; //compile time constant 
    static final Object = new Object(); //initialised at runtime 
    

    आपके मामले में, सिंगलटन आरंभ हो जाएगा डी जब enum वर्ग लोड हो जाता है, यानी पहली बार enumClazz आपके कोड में संदर्भित है।

    तो यह प्रभावी रूप से आलसी है, जब तक आप आप उदाहरण के लिए इस तरह कोड में है, जो अनावश्यक रूप से वर्ग लोड हो रहा है की प्रक्रिया के हिस्से के रूप में अपने सिंगलटन आरंभ होता कहीं एक बयान है:

    Class<?> c = enumClazz.class; 
    
    +0

    वर्ग सिंगलटन {सार्वजनिक स्थिर अंतिम उदाहरण = नया सिंगलटन(); ...} तो, सामान्य वर्ग के तरीके के लिए, यह 'उदाहरण' आलसी शुरू हुआ है? –

    +0

    हां यह आलसी ढंग से उसी तरह शुरू किया जाएगा। – assylias

    +0

    सभी साफ़ हो गए। बहुत बहुत धन्यवाद :) –

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