बिना नाम वाले जावा विधि को कॉल करना


101

मैं नीचे दिए गए कोड को देख रहा हूँ और मुझे कुछ अजीब सा लगा:

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

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

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

मुझे उम्मीद है कि यह एक संकलन त्रुटि देने के System.outसाथ होगा क्योंकि "y" एक विधि घोषणा से संबंधित नहीं है { }। यह क्यों मान्य है? मैं नहीं देखता कि यह कोड कैसे होना चाहिए या कहा जाना चाहिए।

जब यह चल रहा है तो यह x y c gभी पैदा करता है static { }, अनुक्रम निर्माता से पहले क्यों बुलाया जाता है?

जवाबों:


149

यह:

static {
        System.out.print("x ");
    }

एक स्टैटिक इनिशियलाइज़ेशन ब्लॉक है , और क्लास लोड होने पर इसे कहा जाता है। आप अपनी कक्षा में उनमें से जितने चाहें उतने हो सकते हैं, और उन्हें उनकी उपस्थिति (ऊपर से नीचे तक) के क्रम में निष्पादित किया जाएगा।

यह:

    {
        System.out.print("y ");
    }

एक है आरंभीकरण ब्लॉक , और कोड के वर्ग की प्रत्येक निर्माता की शुरुआत में बनाई जाए। इसलिए यदि आपके पास अपनी कक्षा के कई निर्माता हैं, और उन्हें अपनी शुरुआत में कुछ सामान्य करने की आवश्यकता है, तो आपको केवल एक बार कोड लिखना होगा और इसे इस तरह के इनिशियलाइज़ेशन ब्लॉक में डालना होगा ।

इसलिए आपका आउटपुट सही समझ में आता है।

जैसा कि स्टैनली ने नीचे टिप्पणी की थी, अधिक जानकारी के लिए इरिज़ाबिटोन ब्लॉक का वर्णन करने वाले ओरेकल ट्यूटोरियल में अनुभाग देखें।



6
the code is copied into the beginning of each constructor of the class- यह गलत है। मान लीजिए कि कंस्ट्रक्टर के साथ शुरू होता है super("x ");, सुपर कंस्ट्रक्टर किसी भी आरंभीकरण ब्लॉकों से पहले निष्पादित करेगा।
RokL

3
हां, सुपरकंस्ट्रक्टर के लिए निहित और स्पष्ट कॉल को पहले निष्पादित किया जाएगा, अगले ब्लॉक को इनिशियलाइजेशन और बाकी कंस्ट्रक्टर कोड से।
13

25

यह एक विधि नहीं बल्कि एक इनिशियलाइज़ेशन ब्लॉक है

 {
    System.out.print("y ");
 }

इसे कंस्ट्रक्टर कॉल से पहले निष्पादित किया जाएगा। जबकि

static {
        System.out.print("x ");
       }

है स्थिर प्रारंभ ब्लॉक जो जब कक्षा वर्ग लोडर से भरी हुई है निष्पादित किया जाता है।

इसलिए जब आप अपना कोड चलाते हैं
1. क्लास को लोडर द्वारा लोड किया जाता है, तो स्टेटिक इनिशियलाइज़ेशन ब्लॉक को निष्पादित किया जाता है।
आउटपुट: x प्रिंट होता है
। ऑब्जेक्ट बनाया जाता है, इसलिए इनिशियलाइज़ेशन ब्लॉक को निष्पादित किया जाता है और फिर constuctor को
आउटपुट कहा जाता है : y को c
3 के बाद प्रिंट किया जाता है । मुख्य विधि का उपयोग किया जाता है, जो बदले में जाने की विधि का
उत्पादन करती है आउटपुट: छ मुद्रित होता है

अंतिम आउटपुट: xycg
यह http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/ मदद कर सकता है


@ कथुलु: धन्यवाद। यह पिछले सप्ताह तक मान्य था जब मैंने इसे नए लिंक के साथ अपडेट किया है।
xyz

16

यह एक उदाहरण आरंभीकरण ब्लॉक है जिसके बाद एक स्थैतिक आरंभीकरण ब्लॉक होता है

{
    System.out.print("y ");
}

जब आप कक्षा का एक उदाहरण बनाते हैं तो आपको कॉल किया जाता है।

static {
    System.out.print("x ");
}

वर्ग लोडर द्वारा कक्षा को लोड किए जाने पर बुलाया जाता है। तो जब आप करते हैं

new Sequence().go();

वर्ग लोड हो जाता है, इसलिए यह निष्पादित करता है static {}, फिर यह उदाहरण इनिशियलाइज़ेशन ब्लॉक को निष्पादित करता है {}, बाद में कंस्ट्रक्टर के शरीर को बुलाया जाता है, और फिर नए बनाए गए इंस्टेंस पर विधि। उत्पादन को मिटा दें x y c g


15
static {
        System.out.print("x ");
    }

एक स्थिर ब्लॉक है और इसे क्लास लोडिंग के दौरान कहा जाता है

{
    System.out.print("y ");
}

एक है आरंभीकरण ब्लॉक

आपके पास एक वर्ग में कई प्रारंभिक ब्लॉक हो सकते हैं जिस स्थिति में वे उस क्रम में निष्पादित करते हैं जिसमें वे कक्षा में दिखाई देते हैं।

ध्यान दें कि क्लास में मौजूद किसी भी इनिशियलाइज़ेशन ब्लॉक को कंस्ट्रक्टर से पहले निष्पादित किया जाता है।


10
static {
      System.out.print("x ");
}

वर्ग द्वारा साझा किया गया एक इनिशियलाइज़ेशन ब्लॉक है (जैसा कि संकेत दिया गया है static), जिसे पहले निष्पादित किया जाता है।

{
        System.out.print("y ");

}

वर्ग के सभी ऑब्जेक्ट्स (कंस्ट्रक्टर) द्वारा साझा किया गया एक इनिशियलाइज़ेशन ब्लॉक है, जो आगे आता है।

Sequence() {
        System.out.print("c ");
}

वर्ग के लिए एक विशेष रचनाकार है, जिसे तीसरा निष्पादित किया जाता है। उदाहरण आरंभीकरण ब्लॉक को पहले हर बार भेजा जाता है जब निर्माणकर्ता निष्पादित होता है। इसीलिए "c" से ठीक पहले "y" आता है।

void go() {
        System.out.print("g ");
}

ऊपर दिए गए कंस्ट्रक्टर के उपयोग से निर्मित वस्तुओं से जुड़ी एक मात्र विधि है, जो अंतिम आती है।


9
{
    System.out.print("y ");
}

इस तरह के ब्लॉक को कहा जाता है initializer block। जब भी आप इसका उदाहरण बनाते हैं, तब इसे निष्पादित किया जाता है class। संकलन के समय, इस कोड को आपकी कक्षा के प्रत्येक निर्माता में स्थानांतरित कर दिया जाता है।

जहां static initializerब्लॉक के मामले में : -

static {
    System.out.println("x ");
}

जब कक्षा लोड हो जाती है तो इसे एक बार निष्पादित किया जाता है। हम आम तौर पर staticएक staticक्षेत्र के आरंभीकरण के लिए इनिशलाइज़र ब्लॉक का उपयोग करते हैं , कई चरणों की आवश्यकता होती है।


6

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


3
static {
    System.out.print("x ");
}

Static blocksकेवल एक बार क्रियान्वित किया जाता है जब JRE द्वारा कक्षा को लोड और आरंभ किया जाता है।

और हर बार जब आप एक नया उदाहरण बना रहे हैं तोnon-static ब्लॉक कॉल किया जाएगा और यह कंस्ट्रक्टर के ठीक पहले कॉल किया जाएगा।

जैसा कि यहां आपने केवल 1 उदाहरण का Sequenceनिर्माण किया है जिसे non-staticब्लॉकों के बाद बुलाया गया है और फिर विधि जो वास्तव में आपका लक्ष्य है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.