मैंने इस बात को समझने में आधे घंटे बिताए हैं, मैंने अपना कोड ठीक करने में कामयाब रहा है, लेकिन मुझे पूरी तरह समझ नहीं आ रही है कि क्या हो रहा है और आश्चर्य हुआ कि कोई इस पर कुछ प्रकाश डाल सकता है।जावा स्टेटिक फील्ड प्रारंभिकरण
मैं एक utils प्रकार वर्ग, कि है कि हाथ में काम के आधार पर विभिन्न अन्य कार्यक्रमों के द्वारा किया जाता है कुछ स्थिर क्षेत्रों (उदाहरण के लिए एक डेटाबेस कनेक्शन अंतिम बिंदु) शामिल है। अनिवार्य रूप से एक पुस्तकालय।
इस तरह यह पहले देखा गया था (जबकि अभी भी टूटा हुआ है);
//DBUtils.java
public final class DBUtils {
private static DBConnection myDBConnection = spawnDBConnection();
private static DBIndex myDBIndex = null;
private static DBConnection spawnDBConnection() {
//connect to the database
//assign a value to myDBIndex (by calling a method on the DBConnection object) <- IMPORTANT
//myDbIndex NOT NULL HERE
System.out.println("database connection completed");
//return the DBConnection object
}
public static searchDB(String name) {
//use the myDBIndex to find a row and return it
}
}
तो संक्षेप में, मैं दोनों myDBConnection और myDBIndex को कोई मान निर्दिष्ट करने के लिए स्थिर spawnDBConnection() विधि का उपयोग कर रहा हूँ। यह पूरी तरह से काम करता है, मेरे प्रोग्राम से पहली आउटपुट लाइन हमेशा "डेटाबेस कनेक्शन पूर्ण हो जाती है", न ही myDBConnection या myDBIndex spawnDBConnection() विधि के अंत में शून्य हैं, सब कुछ ऐसा होना चाहिए।
मेरा बाहरी कार्यक्रम इस तरह दिखता है;
//DoSomethingUsefulWithTheDatabase.java
public final class DoSomethingUsefulWithTheDatabase {
public static void main(String args[]) {
DBUtils.searchDB("John Smith"); //fails with NullPointerException on myDBIndex!
}
}
searchDB को इस कॉल में होता है के बाद spawnDBConnection समाप्त हो गया है, मैं मानक आउटपुट का इस्तेमाल किया है बड़े पैमाने पर इस दिखाने के लिए। हालांकि, एक बार खोज डीबी विधि के अंदर, myDBIndex का मान शून्य है! यह एक स्थिर क्षेत्र है, और यह spawnDBConnection के अंत तक शून्य नहीं था, कोई अन्य असाइनमेंट नहीं किया गया है, और अब यह शून्य है :(
सरल फिक्स "= null" को हटाने के लिए था इसलिए फ़ील्ड घोषणा अब दिखती है की तरह;
private static DBIndex myDBIndex;
क्यों कि एक फर्क था कि मैं अच्छी तरह से इस एक से उलझन में हूँ
बनाने पर विचार करें आपकी सांख्यिकी 'अंतिम'। इस तरह के आश्चर्य को खत्म करने के लिए आपको उन्हें एक बार असाइन करने के लिए मजबूर होना होगा। –
यह एक भयानक दुःस्वप्न-एंटीपेटर्न है जो आप यहां कर रहे हैं। आप डेटाबेस कनेक्शन के अधिग्रहण के लिए क्लास प्रारंभिक युग्मन कर रहे हैं। –
आपको स्थिर रूप से डीबीसी कनेक्शन शुरू नहीं करना चाहिए। क्या होगा यदि myDBConnection मर जाता है, तो क्या आप अपने कोड में DbUtils2 का उपयोग शुरू करने जा रहे हैं? –