स्थैतिक प्रारंभिक ब्लॉक


265

जहाँ तक मुझे समझ में आया "स्थैतिक आरंभीकरण ब्लॉक" का उपयोग स्थैतिक क्षेत्र के मूल्यों को सेट करने के लिए किया जाता है यदि यह एक पंक्ति में नहीं किया जा सकता है।

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

हमें एक विशेष ब्लॉक में इस तरह की लाइनों की आवश्यकता क्यों है static {...}:?


6
छोटी-मोटी प्रतिक्रिया, लेकिन अगर आप अपनी मान्यताओं को स्पष्ट रूप से बता सकें, तो यह मदद करेगा और इसलिए स्पष्ट करें कि कौन सा उत्तर सही है। जब मैंने पहली बार आपका प्रश्न पढ़ा, तो मैंने गलत समझा और सोचा कि आपको {...}बनाम के बीच का अंतर पता है static {...}। (किस मामले में जॉन स्कीट ने निश्चित रूप से आपके प्रश्न का उत्तर बेहतर तरीके से दिया)
डेविड टी।

1
यह प्रश्न बहुत अस्पष्ट है; आपके पास जवाब देने वाले हैं जो आपके मतलब के बारे में बहुत लंबे-चौड़े अनुमान लगा रहे हैं। कैसे के बारे में स्पष्ट रूप से उदाहरण स्थैतिक आरंभीकरण ब्लॉक आप मन और अपने विकल्प में लिख रहे हैं, ताकि लोगों को जवाब देने के लिए कुछ स्पष्ट हो?
डॉन हैच

जवाबों:


430

गैर स्थिर ब्लॉक:

{
    // Do Something...
}

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

उदाहरण:

public class Test {

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

    {
        System.out.println("Non-static block");
    }

    public static void main(String[] args) {
        Test t = new Test();
        Test t2 = new Test();
    }
}

यह प्रिंट:

Static
Non-static block
Non-static block

106
यह स्वीकृत उत्तर क्यों है? यह सवाल का जवाब भी नहीं देता है।
पॉल बेलोरा

43
यह प्रश्न का उत्तर देता है: "इसे हर बार बुलाया जाता है क्योंकि कक्षा का निर्माण किया जाता है। स्थैतिक ब्लॉक को केवल एक बार कॉल किया जाता है, इससे कोई फर्क नहीं पड़ता कि आप उस प्रकार की कितनी वस्तुएं बनाते हैं।"
एडम एरॉल्ड

83
जिज्ञासु पाठक के लिए, गैर-स्थैतिक ब्लॉक को वास्तव में जावा कंपाइलर द्वारा कक्षा ( स्रोत ) के प्रत्येक कंस्ट्रक्टर में कॉपी किया जाता है । तो यह अभी भी खेतों को इनिशियलाइज़ करना कंस्ट्रक्टर का काम है।
मार्टिन एंडरसन

2
स्वीकृत उत्तर यह होना चाहिए: stackoverflow.com/a/2420404/363573 । यह उत्तर एक वास्तविक जीवन उदाहरण प्रस्तुत करता है जहां आपको स्थिर ब्लॉकों की आवश्यकता होती है।
Stephan

16
यह जवाब अचानक क्यों कम हो रहा है? आप इस स्वीकृत जवाब के बारे में असहमत हो सकते हैं, लेकिन यह निश्चित रूप से किसी भी तरह से गलत या भ्रामक नहीं है। यह बस एक सरल उदाहरण के साथ इन भाषा निर्माणों की समझ में मदद करने की कोशिश कर रहा है।
फ्रेडरिक वर्डेंस्कॉल्ड

132

यदि वे एक स्थिर इनिशियलाइज़ेशन ब्लॉक में नहीं थे, तो वे कहाँ होंगे? आप एक वैरिएबल की घोषणा कैसे करेंगे जो केवल आरंभिक उद्देश्यों के लिए स्थानीय था, और इसे एक क्षेत्र से अलग करना था? उदाहरण के लिए, आप कैसे लिखना चाहेंगे:

public class Foo {
    private static final int widgets;

    static {
        int first = Widgets.getFirstCount();
        int second = Widgets.getSecondCount();
        // Imagine more complex logic here which really used first/second
        widgets = first + second;
    }
}

तो firstऔर secondएक ब्लॉक में नहीं थे, वे क्षेत्रों की तरह लग रही होगी। अगर वे बिना एक ब्लॉक में थे staticउसके सामने, कि, एक उदाहरण प्रारंभ ब्लॉक के बजाय एक स्थिर प्रारंभ ब्लॉक के रूप में गिनती तो यह एक बार निष्पादित किया जाएगा प्रति निर्माण उदाहरण के बजाय एक बार में कुल।

अब इस विशेष मामले में, आप इसके बजाय एक स्थिर विधि का उपयोग कर सकते हैं:

public class Foo {
    private static final int widgets = getWidgets();

    static int getWidgets() {
        int first = Widgets.getFirstCount();
        int second = Widgets.getSecondCount();
        // Imagine more complex logic here which really used first/second
        return first + second;
    }
}

... लेकिन यह तब काम नहीं करता है जब आप एक ही ब्लॉक में एक से अधिक वैरिएबल असाइन करना चाहते हैं, या कोई नहीं (जैसे यदि आप बस कुछ लॉग इन करना चाहते हैं - या शायद एक देशी लाइब्रेरी को इनिशियलाइज़ कर सकते हैं)।


1
क्या स्थिर वैरिएबल को स्थिर करने से पहले या उसके बाद स्थिर ब्लॉक होता है? private static int widgets = 0; static{widgets = 2;}
वीशी ज़ेंग

1
स्थिर चर से पहले या बाद में स्थैतिक ब्लॉक होने के बारे में उत्सुक था। उदाहरण के लिए private static int widgets = 0; static{widgets = 2;}पता चला कि '=' असाइनमेंट क्रम में होता है, जिसका अर्थ है कि 'पहले' को पहले असाइन किया जाएगा। उपर्युक्त उदाहरण 'विगेट्स' को 2 का मान देगा (PS को पता नहीं था कि टिप्पणियों को केवल 5 मिनट में संपादित किया जा सकता है ...)
वीशी ज़ेंग

@WeishiZeng: हाँ, यह दस्तावेज़ों के अनुसार है ।oracle.com / javase / specs / jls / se8 / html/… - point 9.
जॉन स्कीट

लेकिन क्या आप एक निजी स्थैतिक विधि का भी उपयोग नहीं कर सकते हैं जिसमें स्थैतिक आरंभीकरण खंड के समान सटीक कोड हो और निजी स्थिर विधि के लिए विजेट असाइन करें?
ज़ाचरी क्रूस

1
@Zachary: क्या आपका मतलब है कि मूल्य वापस करना, और विधि कॉल का परिणाम निर्दिष्ट करना? यदि हां, तो - जब आप ब्लॉक के परिणामस्वरूप बिल्कुल एक चर को असाइन कर रहे हैं । लगभग 7 घंटे में विवरण के साथ मेरे उत्तर को संपादित करेंगे ...
जॉन स्कीट

103

यहाँ एक उदाहरण है:

  private static final HashMap<String, String> MAP = new HashMap<String, String>();
  static {
    MAP.put("banana", "honey");
    MAP.put("peanut butter", "jelly");
    MAP.put("rice", "beans");
  }

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

गैर-स्थैतिक आरम्भिक ब्लॉक होना भी संभव है। वे वर्ग के लिए परिभाषित निर्माण विधियों के सेट के विस्तार की तरह काम करते हैं। वे केवल स्थिर इनिलाइज़र ब्लॉक की तरह दिखते हैं, सिवाय इसके कि "स्थिर" कीवर्ड को छोड़ दिया जाए।


4
उस विशेष उदाहरण के लिए कभी-कभी डबल ब्रेस पैटर्न का "दुरुपयोग" किया गया है :)
BalusC

इसका दुरुपयोग किया जा सकता है, लेकिन दूसरी ओर यह कुछ गंदगी को साफ करता है, और कुछ प्रकार के कोड को थोड़ा और "ठोस" बनाता है। मैं मज़े के लिए एरलांग में कार्यक्रम करता हूं, और आपको स्थानीय चर की आवश्यकता न होने पर झुका हुआ है :-)
पॉइन्टी

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

हम AfterPropertiesSet विधि के बाद में InitializingBean का उपयोग करने के साथ ऐसा कर सकते हैं?
उदाहरणार्थ

48

यह तब भी उपयोगी है जब आप वास्तव में किसी भी चीज को मूल्य नहीं देना चाहते हैं, जैसे कि रनटाइम के दौरान केवल एक बार कुछ क्लास लोड करना ।

उदाहरण के लिए

static {
    try {
        Class.forName("com.example.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        throw new ExceptionInInitializerError("Cannot load JDBC driver.", e);
    }
}

अरे, एक और लाभ है, आप इसका उपयोग अपवादों को संभालने के लिए कर सकते हैं। कल्पना कीजिए कि getStuff()यहाँ Exceptionजो वास्तव में एक पकड़ ब्लॉक में है फेंकता है:

private static Object stuff = getStuff(); // Won't compile: unhandled exception.

फिर एक staticइनिशाइज़र यहाँ उपयोगी है। आप वहां अपवाद को संभाल सकते हैं।

एक अन्य उदाहरण बाद में सामान देने का है जो असाइन करने के दौरान नहीं किया जा सकता है:

private static Properties config = new Properties();

static {
    try { 
        config.load(Thread.currentThread().getClassLoader().getResourceAsStream("config.properties");
    } catch (IOException e) {
        throw new ExceptionInInitializerError("Cannot load properties file.", e);
    }
}

JDBC ड्राइवर उदाहरण पर वापस आने के लिए, कोई भी सभ्य JDBC ड्राइवर खुद को staticशुरू करने के लिए इनिशियलाइज़र का उपयोग करता है DriverManagerइसे और इस उत्तर को भी देखें ।


2
इसमें खतरनाक वूडू निहित है ... सिंथेटिक क्लिनिट () पद्धति में स्टेटिक इनिशियलाइज़र चलाए जाते हैं, जो कि निहित है । इसका मतलब यह है कि जेवीएम क्लासफाइल पर विचाराधीन ताला लगा देगा। यदि दो वर्ग एक-दूसरे को लोड करने का प्रयास करते हैं, और प्रत्येक एक अलग थ्रेड में लोड करना शुरू कर देता है, तो यह मल्टीथ्रेडेड वातावरण में गतिरोध पैदा कर सकता है। Www-01.ibm.com/support/docview.wss?uid=swg1IV48872
Ajax

@ अजाक्स: मैं इस प्रश्न में या तो JDBC ड्राइवर या बग को लोड करने के लिए जिम्मेदार एप्लिकेशन कोड में एक बग समझूंगा। आमतौर पर, सभ्य JDBC ड्राइवरों के मामले में, जब तक आप इसे एप्लिकेशन के स्टार्टअप के दौरान केवल एक बार आवेदन भरते हैं, तब तक कुछ भी नहीं होता है।
बालुसक ११'१६ को

यह निश्चित रूप से एक बग होगा लेकिन पूरी तरह से जेडीबीसी चालक की गलती नहीं होगी। हो सकता है कि चालक के पास निर्दोष रूप से अपने स्वयं के स्थैतिक आरंभीकरणकर्ता हों, और हो सकता है कि आप अपने वर्ग में कुछ अन्य लोगों के साथ-साथ इस वर्ग को जन्मजात रूप से आरंभ करें, और, ओह नहीं, कुछ अनपेक्षित वर्ग एक-दूसरे को चक्रीय रूप से लोड करते हैं, और अब आपका अनुप्रयोग गतिरोध। मैंने java.awt.AWTEvent और sun.util.logging.PlatformLogger के बीच गतिरोध के लिए इस धन्यवाद की खोज की। मैंने केवल हेडलाइट चलाने के लिए यह बताने के लिए AWTEvent को छुआ, और PlatformLogger को लोड करने के लिए कुछ अन्य लिबास ... जो AWTEvent लोड करता है।
अजाक्स

1
दोनों वर्गों के घाव अलग-अलग धागों पर सिकुड़े हुए हैं, और मेरा निर्माण लगभग 1/150 रन गतिरोध है। इसलिए, मैं अब स्टैटिक ब्लॉक में क्लास लोडिंग पर बहुत अधिक सावधान हूं। इस मामले में, मैंने ऊपर उल्लेख किया है, एक आस्थगित प्रदाता पैटर्न का उपयोग करके जहां मैं तुरंत एक अंतरिम प्रदाता वर्ग बना सकता हूं (गतिरोध की कोई संभावना नहीं है), क्षेत्र को इनिशियलाइज़ करें, और तब जब यह वास्तव में एक्सेस किया जाता है (गैर-सिंक्रनाइज़ फ़ील्ड एक्सेस में), फिर मैं वास्तव में उन कक्षाओं को लोड करता हूं जो गतिरोध का कारण बन सकते हैं।
अजाक्स

11

मैं कहूंगा कि static blockसिंटैक्टिक शुगर है। ऐसा कुछ भी नहीं है जिसे आप staticब्लॉक के साथ कर सकते हैं और कुछ और के साथ नहीं।

यहां पोस्ट किए गए कुछ उदाहरणों का फिर से उपयोग करने के लिए।

कोड का यह टुकड़ा staticआरम्भिक का उपयोग किए बिना फिर से लिखा जा सकता है ।

विधि # 1: साथ static

private static final HashMap<String, String> MAP;
static {
    MAP.put("banana", "honey");
    MAP.put("peanut butter", "jelly");
    MAP.put("rice", "beans");
  }

विधि # 2: बिना static

private static final HashMap<String, String> MAP = getMap();
private static HashMap<String, String> getMap()
{
    HashMap<String, String> ret = new HashMap<>();
    ret.put("banana", "honey");
    ret.put("peanut butter", "jelly");
    ret.put("rice", "beans");
    return ret;
}

10

कुछ वास्तविक कारण हैं जिनका अस्तित्व होना आवश्यक है:

  1. आरंभ static finalजिन सदस्यों की आरंभीकरण एक अपवाद फेंक सकती है
  2. static finalगणना किए गए मानों के साथ सदस्यों को आरंभ करना

लोग static {}ब्लॉक का उपयोग उन चीजों को शुरू करने के लिए एक सुविधाजनक तरीके के रूप में करते हैं जो वर्ग रनटाइम के भीतर भी निर्भर करता है - जैसे कि यह सुनिश्चित करना कि विशेष वर्ग लोड किया गया है (जैसे, JDBC ड्राइवर)। जो अन्य तरीकों से किया जा सकता है; हालाँकि, जिन दो चीजों का मैं ऊपर उल्लेख करता हूं, वे केवल static {}ब्लॉक जैसे निर्माण के साथ ही की जा सकती हैं ।


8

स्थिर खंडों में किसी ऑब्जेक्ट के निर्माण से पहले आप एक बार एक वर्ग के लिए कोड के बिट्स निष्पादित कर सकते हैं।

उदाहरण के लिए

class A {
  static int var1 = 6;
  static int var2 = 9;
  static int var3;
  static long var4;

  static Date date1;
  static Date date2;

  static {
    date1 = new Date();

    for(int cnt = 0; cnt < var2; cnt++){
      var3 += var1;
    }

    System.out.println("End first static init: " + new Date());
  }
}

7

यह सोचना एक आम भ्रांति है कि एक स्थिर ब्लॉक में केवल स्थिर क्षेत्रों तक ही पहुंच होती है। इसके लिए मैं नीचे दिए गए कोड ऑफ कोड दिखाना चाहूंगा जो मैं अक्सर वास्तविक जीवन की परियोजनाओं में उपयोग करता हूं ( थोड़े अलग संदर्भ में दूसरे उत्तर से आंशिक रूप से कॉपी किया गया ):

public enum Language { 
  ENGLISH("eng", "en", "en_GB", "en_US"),   
  GERMAN("de", "ge"),   
  CROATIAN("hr", "cro"),   
  RUSSIAN("ru"),
  BELGIAN("be",";-)");

  static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>(); 
  static { 
    for (Language l:Language.values()) { 
      // ignoring the case by normalizing to uppercase
      ALIAS_MAP.put(l.name().toUpperCase(),l); 
      for (String alias:l.aliases) ALIAS_MAP.put(alias.toUpperCase(),l); 
    } 
  } 

  static public boolean has(String value) { 
    // ignoring the case by normalizing to uppercase
    return ALIAS_MAP.containsKey(value.toUpper()); 
  } 

  static public Language fromString(String value) { 
    if (value == null) throw new NullPointerException("alias null"); 
    Language l = ALIAS_MAP.get(value); 
    if (l == null) throw new IllegalArgumentException("Not an alias: "+value); 
    return l; 
  } 

  private List<String> aliases; 
  private Language(String... aliases) { 
    this.aliases = Arrays.asList(aliases); 
  } 
} 

यहाँ इनिशलाइज़र का उपयोग इंडेक्स ( ALIAS_MAP) को बनाए रखने के लिए किया जाता है , जिससे एलियम का एक सेट मूल एनुम प्रकार पर वापस आ सके। यह Enumस्वयं के द्वारा प्रदान की गई अंतर्निहित वैल्यूऑफ पद्धति के विस्तार के रूप में करना है।

जैसा कि आप देख सकते हैं, स्टैटिक इनिशियलाइज़र privateक्षेत्र में भी पहुँचता है aliases। यह समझना महत्वपूर्ण है कि staticब्लॉक में पहले से ही Enumमूल्य उदाहरणों (जैसे ENGLISH) तक पहुंच है । ऐसा इसलिए है क्योंकि प्रकारों के मामले में आरंभीकरण और निष्पादन का क्रमEnum , जैसे static privateकि staticब्लॉकों को उदाहरणों से पहले उदाहरणों से आरम्भ किया गया है:

  1. Enumस्थिरांक जो निहित स्थिर क्षेत्र हैं। इसके लिए Enum कंस्ट्रक्टर और उदाहरण ब्लॉक की आवश्यकता होती है, और उदाहरण इनिशियलाइज़ेशन पहले भी होता है।
  2. static घटना के क्रम में स्थिर क्षेत्रों के ब्लॉक और आरंभीकरण।

यह आउट-ऑफ-ऑर्डर आरंभीकरण ( staticब्लॉक से पहले निर्माणकर्ता ) नोट करने के लिए महत्वपूर्ण है। यह तब भी होता है जब हम एक सिंगलटन (उदाहरण के लिए बनाए गए) जैसे उदाहरणों के साथ स्थैतिक क्षेत्रों को आरंभ करते हैं:

public class Foo {
  static { System.out.println("Static Block 1"); }
  public static final Foo FOO = new Foo();
  static { System.out.println("Static Block 2"); }
  public Foo() { System.out.println("Constructor"); }
  static public void main(String p[]) {
    System.out.println("In Main");
    new Foo();
  }
}

हम जो देखते हैं वह निम्न आउटपुट है:

Static Block 1
Constructor
Static Block 2
In Main
Constructor

स्पष्ट है कि स्थिर आरंभीकरण वास्तव में कंस्ट्रक्टर से पहले हो सकता है , और उसके बाद भी:

बस मुख्य विधि में फू तक पहुँचने, वर्ग लोड होने का कारण बनता है और स्थैतिक आरंभीकरण शुरू होता है। लेकिन स्टेटिक इनिशियलाइज़ेशन के एक भाग के रूप में हम फिर से स्टैटिक फ़ील्ड्स के लिए कंस्ट्रक्टरों को कॉल करते हैं, जिसके बाद यह स्टैटिक इनिशियलाइज़ेशन को फिर से शुरू करता है, और मेन मेथड के भीतर से बुलाए गए कंस्ट्रक्टर को पूरा करता है। इसके बजाय जटिल स्थिति जिसके लिए मुझे उम्मीद है कि सामान्य कोडिंग में हमें निपटना नहीं होगा।

इस बारे में अधिक जानकारी के लिए " प्रभावी जावा " पुस्तक देखें ।


1
एक्सेस करने का aliasesमतलब यह नहीं है कि स्टैटिक ब्लॉक नॉन स्टैटिक सदस्यों तक पहुँच सकता है। / स्थिर / विधि द्वारा लौटाए गए मूल्यों के aliasesमाध्यम से पहुँचा है । जैसा कि आप उल्लेख करते हैं, तथ्य यह है कि एनम चर पहले से ही उस बिंदु पर उपलब्ध हैं असामान्य बिट - नियमित वर्गों के गैर स्थिर सदस्य इस स्थिति में सुलभ नहीं होंगे। Languagevalues()
इग्नाजियो

स्टैटिक ब्लॉक अभी भी केवल स्टैटिक फील्ड (आपके एनम इंग्लिश, जर्मन, ... के मामले में) तक पहुंच रहा है, जो इस मामले में ऑब्जेक्ट हैं। चूंकि स्थैतिक क्षेत्र स्वयं ऑब्जेक्ट हैं, आप स्थैतिक ऑब्जेक्ट के इंस्टेंस फ़ील्ड तक पहुँच सकते हैं।
स्वामी पीआर

1
class Foo { static final Foo Inst1; static final Foo Inst2; static{ Inst1 = new Foo("Inst1"); Inst2 = new Foo("Inst2"); } static { System.out.println("Inst1: " + Inst1.member); System.out.println("Inst2: " + Inst2.member); } private final String member; private Foo(String member){ this.member = member; } } उपरोक्त कोड एनम उदाहरण से अलग नहीं है और अभी भी स्टेटिक ब्लॉक के अंदर इंस्टेंस वैरिएबल के एक्सेस की अनुमति देता है
स्वामी पीआर

@SwamiPR वास्तव में इसे संकलित करता है, मेरे आश्चर्य को, और मुझे इस बात से सहमत होना होगा कि कोड सिद्धांत रूप में भिन्न नहीं है। मुझे जावा युक्ति को फिर से पढ़ना है, मुझे लगता है कि कुछ ऐसा है जो मुझे याद है। अच्छी प्रतिक्रिया वापस, धन्यवाद।
योयो

@SwamiPR मुद्दा वास्तव में यह है कि हमें एक का उपयोग करना चाहिए Enum। यह गारंटी देने का सबसे अच्छा तरीका है कि हम एकवचन उदाहरणों की ओर इशारा कर रहे हैं '- यहाँ देखें । और आपके बिंदुओं के लिए, मैंने कई अपडेट किए हैं।
यो

3

यदि आपके स्टैटिक वैरिएबल को रनटाइम पर सेट करने की आवश्यकता है तो एक static {...}ब्लॉक बहुत मददगार है।

उदाहरण के लिए, यदि आपको स्थिर सदस्य को एक मान फ़ाइल या डेटाबेस में संग्रहीत करने के लिए आवश्यक है।

तब भी उपयोगी है जब आप एक स्थिर Mapसदस्य के लिए मान जोड़ना चाहते हैं क्योंकि आप प्रारंभिक सदस्य घोषणा में इन मूल्यों को नहीं जोड़ सकते हैं।


3

तो आपके पास एक स्थिर क्षेत्र है (इसे "वर्ग चर" भी कहा जाता है क्योंकि यह वर्ग के एक उदाहरण के बजाय वर्ग से संबंधित है; दूसरे शब्दों में यह किसी वस्तु के बजाय कक्षा से जुड़ा हुआ है) और आप इसे प्रारंभ करना चाहते हैं। इसलिए यदि आप इस वर्ग का उदाहरण नहीं बनाना चाहते हैं और आप इस स्थिर क्षेत्र में हेरफेर करना चाहते हैं, तो आप इसे तीन तरीकों से कर सकते हैं:

1- जब आप वैरिएबल घोषित करते हैं, तो इसे केवल इनिशियलाइज़ करें:

static int x = 3;

2- एक स्थिर प्रारंभिक ब्लॉक है:

static int x;

static {
 x=3;
}

3 - एक क्लास मेथड (स्थैतिक विधि) है जो क्लास वैरिएबल तक पहुँचता है और इसे इनिशियलाइज़ करता है: यह उपरोक्त स्टैटिक ब्लॉक का विकल्प है; आप एक निजी स्थैतिक विधि लिख सकते हैं:

public static int x=initializeX();

private static int initializeX(){
 return 3;
}

अब आप स्थैतिक तरीकों के बजाय स्थैतिक आरम्भिक ब्लॉक का उपयोग क्यों करेंगे?

यह वास्तव में आपके कार्यक्रम की जरूरत है। लेकिन आपको यह जानना होगा कि स्थिर आरंभीकरण ब्लॉक को एक बार कहा जाता है और वर्ग विधि का एकमात्र लाभ यह है कि बाद में उन्हें फिर से उपयोग किया जा सकता है यदि आपको वर्ग चर को फिर से संगठित करने की आवश्यकता है।

मान लीजिए कि आपके कार्यक्रम में एक जटिल सरणी है। आप इसे आरंभीकृत करते हैं ( उदाहरण के लिए लूप के लिए) और फिर इस सरणी में मान पूरे कार्यक्रम में बदल जाएंगे लेकिन फिर कुछ बिंदु पर आप इसे फिर से संगठित करना चाहते हैं (प्रारंभिक मूल्य पर वापस जाएं)। इस स्थिति में आप निजी स्थैतिक विधि कह सकते हैं। यदि आप मूल्यों को सुदृढ़ करने के लिए अपने कार्यक्रम में आवश्यकता नहीं रखते हैं, तो आप केवल स्थैतिक ब्लॉक का उपयोग कर सकते हैं और स्थैतिक विधि की कोई आवश्यकता नहीं है क्योंकि आप इसे कार्यक्रम में बाद में उपयोग नहीं करने वाले हैं।

नोट: स्थैतिक ब्लॉकों को उस क्रम में कहा जाता है, जो वे कोड में दिखाई देते हैं।

उदाहरण 1:

class A{
 public static int a =f();

// this is a static method
 private static int f(){
  return 3;
 }

// this is a static block
 static {
  a=5;
 }

 public static void main(String args[]) {
// As I mentioned, you do not need to create an instance of the class to use the class variable
  System.out.print(A.a); // this will print 5
 }

}

उदाहरण 2:

class A{
 static {
  a=5;
 }
 public static int a =f();

 private static int f(){
  return 3;
 }

 public static void main(String args[]) {
  System.out.print(A.a); // this will print 3
 }

}

0

पूरक के रूप में, @Pointy ने कहा

"स्टैटिक" सेक्शन (कोड) को कोड को क्लास लोड समय पर निष्पादित किया जाएगा, इससे पहले कि क्लास के किसी भी इंस्टेंसेस का निर्माण किया जाए (और इससे पहले कि कोई स्टैटिक तरीके कहीं और से बुलाए जाएं)।

इसे System.loadLibrary("I_am_native_library")स्टैटिक ब्लॉक में जोड़ना है ।

static{
    System.loadLibrary("I_am_a_library");
}

यह गारंटी देगा कि संबंधित लाइब्रेरी को मेमोरी में लोड करने से पहले कोई मूल विधि नहीं कहा जाएगा।

Oracle से loadLibrary के अनुसार :

यदि यह विधि एक ही लाइब्रेरी नाम के साथ एक से अधिक बार कॉल की जाती है, तो दूसरी और बाद की कॉल को अनदेखा कर दिया जाता है।

इतना अप्रत्याशित रूप से, पुस्तकालय से बहु-लोड होने से बचने के लिए System.loadLibrary का उपयोग नहीं किया जाता है।


0

आपको पहले यह समझने की आवश्यकता है java.class.Classकि रनटाइम के दौरान आपके एप्लिकेशन क्लासेस स्वयं ऑब्जेक्ट्स पर त्वरित हैं। यह तब होता है जब आपके स्थिर ब्लॉक चलते हैं। तो आप वास्तव में ऐसा कर सकते हैं:

public class Main {

    private static int myInt;

    static {
        myInt = 1;
        System.out.println("myInt is 1");
    }

    //  needed only to run this class
    public static void main(String[] args) {
    }

}

और यह सांत्वना देने के लिए "myInt 1 है" प्रिंट करेगा। ध्यान दें कि मैंने किसी भी वर्ग को त्वरित नहीं किया है।


0
static int B,H;
static boolean flag = true;
static{
    Scanner scan = new Scanner(System.in);
    B = scan.nextInt();
    scan.nextLine();
    H = scan.nextInt();

    if(B < 0 || H < 0){
        flag = false;
        System.out.println("java.lang.Exception: Breadth and height must be positive");
    } 
}

-1

स्टेटिक ब्लॉक का उपयोग किसी भी टेक्नोलॉजी के लिए डायनामिक तरीके से स्टैटिक डेटा मेंबर को इनिशियलाइज़ करने के लिए किया जाता है, या हम कह सकते हैं कि स्टेटिक डेटा मेंबर स्टैटिक ब्लॉक के डायनामिक इनिशियलाइज़ेशन के लिए इस्तेमाल किया जा रहा है। लेकिन नॉन स्टैटिक डेटा मेंबर इनिशियलाइज़ेशन के लिए हमारे पास कंस्ट्रक्टर है लेकिन हमारे पास नहीं है ऐसी कोई भी जगह जहां हम स्थैतिक डेटा सदस्य को गतिशील रूप से आरंभ कर सकते हैं

Eg:-class Solution{
         // static int x=10;
           static int x;
       static{
        try{
          x=System.out.println();
          }
         catch(Exception e){}
        }
       }

     class Solution1{
      public static void main(String a[]){
      System.out.println(Solution.x);
        }
        }

अब मेरा स्टेटिक int x डायनामिक रूप से इनिशियलाइज़ कर देगा ।Bcoz जब कंपाइलर Solution.x पर जाएगा, तो सॉल्यूशन क्लास को लोड करेगा और क्लास लोडिंग टाइम पर स्टैटिक ब्लॉक लोड होगा। तो क्या हम उस स्टैटिक डेटा मेंबर को डायनामिकली इनिशियलाइज़ कर सकते हैं।

}

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