2009-11-15 13 views
6

क्या कोई मुझे बता सकता है कि निम्नलिखित क्या है?जावा: स्थैतिक {} क्या है?

public class Stuff 
{ 
    static 
    { 
     try 
     { 
      Class.forName("com.mysql.jdbc.Driver"); 
     } 
     catch (ClassNotFoundException exception) 
     { 
      log.error("ClassNotFoundException " + exception.getMessage()); 
     } 
... 
} 

यह स्थिर {...} क्या करता है?

मुझे सी ++ से स्थिर चर के बारे में पता है, लेकिन क्या यह एक स्थिर ब्लॉक या कुछ है?

यह सामान कब निष्पादित किया जा रहा है?

+0

डुपे। http://stackoverflow.com/questions/335311/java-static-keyword – finnw

उत्तर

14

स्थिर ब्लॉक को class static initializer कहा जाता है - यह पहली बार कक्षा लोड होने पर चला जाता है (और यह एकमात्र समय है जब यह चलाया जाता है [फुटनोट])।

उस विशेष ब्लॉक का उद्देश्य यह जांचना है कि MySQL ड्राइवर क्लासपाथ पर है (और यदि यह नहीं है तो फेंक/लॉग त्रुटि)।


[फुटनोट] एक बार classloader प्रति स्थिर ब्लॉक रन उस वर्ग (इसलिए यदि आप एक से अधिक वर्ग लोडर कि एक दूसरे (जैसे उदाहरण के लिए प्रतिनिधि नहीं है) से भिन्न हैं पड़ा लोड करता है, यह एक बार निष्पादित किया जाएगा प्रत्येक।

+1

"यह पहली बार कक्षा लोड होने पर चला जाता है (और यह केवल एक बार चल रहा है)।" - क्या यह प्रति वर्ग लोडर एक बार नहीं चलाता है जो कक्षा को लोड करता है? तकनीकी मुझे पता है लेकिन यह उल्लेखनीय लायक हो सकता है। – Grundlefleck

+0

इस मामले में, MySQL ड्राइवर की जांच करने के लिए यह सब कुछ नहीं किया जा रहा है: क्लास को इंस्टेंट करने से स्वचालित रूप से DriverManager के साथ इसे पंजीकृत किया जाता है। बाद में डीबी कनेक्ट() कथन में MySQL URL का जवाब देने के लिए यह आवश्यक है। –

+1

यदि कैच क्लॉज ने त्रुटि को लॉगिंग करने के बजाय रनटाइम एक्सेप्शन फेंक दिया है, तो क्लास स्टफ को लोड करना निरस्त कर दिया जाएगा और इसके किसी भी संदर्भ से रनटाइम पर NoClassDefFoundError का कारण होगा। – Henry

8

स्थैतिक प्रारंभकर्ता ब्लॉक का प्राथमिक उपयोग प्रारंभिकरण के विभिन्न बिट्स करना है जो कि कन्स्ट्रक्टर के अंदर उचित नहीं हो सकता है, जैसे कि कन्स्ट्रक्टर और प्रारंभकर्ताओं ने एक साथ बनाई गई नई स्थिति को उस राज्य में रखा जो पूरी तरह से उपयोग के लिए संगत है

रचनाकारों के विपरीत, उदाहरण के लिए, स्थिर प्रारंभकर्ता एस विरासत में नहीं हैं और जब कक्षा लोड हो जाती है और जेआरई द्वारा शुरू किया जाता है तो केवल तभी निष्पादित किया जाता है। ऊपर दिए गए उदाहरण में, प्रारंभिक पूर्ण होने के बाद क्लास वेरिएबल foo के पास मूल्य 998877 होगा।

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

+0

* स्टेटिक * प्रारंभकर्ता ब्लॉक (कन्स्ट्रक्टर और सामान्य प्रारंभकर्ता ब्लॉक के विपरीत) वास्तव में * ऑब्जेक्ट * प्रारंभिकता के साथ कुछ भी नहीं करना है। – Henry

1

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

final static String JDBC_DRIVER = getJdbcDriver(); 

static 
{ 
    try 
    { 
    Class.forName(JDBC_DRIVER); 
    } 
    catch (ClassNotFoundException exception) 
    { 
    log.error("ClassNotFoundException " + exception.getMessage()); 
    } 
} 

इस उदाहरण getJdbcDriver में स्थिर प्रारंभकर्ता से पहले मार डाला जाएगा। इसके अलावा, कक्षा में 1 से अधिक स्थिर प्रारंभकर्ता हो सकते हैं। एक बार फिर वे उपस्थिति के क्रम में निष्पादित कर रहे हैं।

मैं यहां उदाहरण प्रारंभकर्ताओं के अस्तित्व का भी उल्लेख करना चाहता हूं, क्योंकि पहली बार देखा जाने पर वे आश्चर्यचकित हो जाते हैं। वे कक्षा के शरीर के अंदर एक कोड ब्लॉक की तरह दिखते हैं।

class MyClass 
{ 
    final int intVar; 

    { 
    intVar = 1; 
    } 
} 

सामान्य स्थिति में उनके उपयोग निर्माता की वजह से कुछ हद तक अनावश्यक है, है, लेकिन वे बंद होने के जावा के संस्करण को लागू करने में उपयोगी होते हैं।

1

जब भी कक्षा पहली बार लोड की जाती है तो स्थैतिक प्रारंभकर्ता ब्लॉक निष्पादित हो जाता है। ऐसा तब हो सकता है जब उच्च स्तर पर कुछ पहली बार प्रश्न पर कक्षा में Class#forName("yourpackage.YourClass") या new YourClass() कर रहा हो।

एक संयोग से, सभ्य जेडीबीसी ड्राइवरों के पास कुछ समान है।वे अर्थात् DriverManager में खुद को पंजीकृत करता है एक स्थिर प्रारंभकर्ता ब्लॉक का उपयोग:

static { 
    DriverManager.registerDriver(new ThisDriver()); 
} 

इसलिए जब भी आप एक Class.forName("somepackage.ThisDriver") करते हैं, आप को प्रभावी ढंग से DriverManager में चालक पंजीकृत करेंगे कि ताकि आप इसे से एक कनेक्शन बाद में मिल सकती है।

1

उपरोक्त सभी के अतिरिक्त, कक्षा कन्स्ट्रक्टर और कक्षा प्रारंभकर्ता का उपयोग करने में एक मिनट का अंतर है। कन्स्ट्रक्टर जैसा कि हम जानते हैं कि आमतौर पर ऑब्जेक्ट्स को आरंभ करने के लिए उपयोग किया जाएगा और यदि हमारे पास स्थैतिक चर हैं तो कक्षा को लोड होने पर उन्हें प्रारंभ करने के लिए आमतौर पर स्थैतिक ब्लॉक का उपयोग किया जाता है।

जब हमारे पास स्थैतिक चर और स्थिर ब्लॉक होते हैं तो स्थैतिक चर पहले और फिर ब्लॉक प्रारंभ होते हैं।

जब कक्षा पहली बार लोड की जाती है, तो स्थिर ब्लॉक क्लास कन्स्ट्रक्टर से पहले शुरू होता है।

0

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

  • है कोड का एक सामान्य ब्लॉक

  • यह ब्रेसिज़ {}

  • यह स्थिर कीवर्ड से पहले किया जाता है में संलग्न है

    class Foo { 
        static { 
         // initialization code goes here: 
         doSomething(); 
        } 
    } 
    
  • वर्ग स्थिर प्रारंभ ब्लॉक

    के किसी भी संख्या हो सकती है
  • वे कक्षा शरीर

  • वे कोड

में apperence के क्रम में कहा जाता है में कहीं भी दिखाई दे सकती है एक स्थिर प्रारंभ ब्लॉक करने के लिए वैकल्पिक:

  • एक निजी स्थिर विधि लिखने
  • और इसे स्थैतिक वर्ग परिवर्तनीय

इस दृष्टिकोण का लाभ यह है कि स्थिर विधि को कक्षा चर को पुन: प्रारंभ करने के लिए बाद में लागू किया जा सकता है।

class Foo { 
    public static int myVar = initializeClassVariable(); 

    private static int initializeClassVariable() { 
     // initialization code goes here: 
     int v = 255; 
     return v; 
    } 
} 
संबंधित मुद्दे