2015-10-20 10 views
6

ठीक है, मैं इस तरह के एक कोड मिल गया है:जब कक्षाएं लोड की जाती हैं?

public class Main { 
    public static void main(String[] args) { 
     Test t; //1 
     Integer i = new Integer(1); //2 
     t = new Test(); //3 
     System.out.println(Test4.a); //4 
    } 
} 

class Test { 
    private int a = 10; 
    private Test2 t2; //5 

    List<Test2> list = new ArrayList<Test2>() { 
     { 
      for (int i = 0; i < a; i++) { 
       add(new Test2()); //6 
      } 
     } 
    }; 
} 

class Test2 extends Test3{ 
} 

class Test3 { 
} 

class Test4 { 
    public static final int a = 4; 
} 

मैं कैसे (पूरी तरह या आंशिक) और जब कक्षाओं लोड किए गए हैं पता नहीं है। तो:

  1. Test t; - यह एक सक्रिय उपयोग नहीं है, लेकिन संदर्भ t की एक निश्चित प्रकार होना चाहिए। टेस्ट क्लास लोड किया गया था (शायद आंशिक रूप से, फिर कितने चरण - लोडिंग \ लिंकिंग \ प्रारंभ करना - यह पारित हुआ) या कुछ भी नहीं हुआ?
  2. Integer i = new Integer(1); - जेवीएम शुरू होने पर या इस लाइन पर इंटीजर लोड किया गया था?
  3. t = new Test(); - एक सक्रिय उपयोग। क्या यह शुरुआत से या किसी बिंदु से पूरी तरह से लोड किया गया था (देखें 1)
  4. System.out.println(Test4.a); - Test4 लोड किया गया था या नहीं?
  5. Test2 और Test3 लोड या नहीं थे? यदि हां तो कब?

उत्तर

5

जब कक्षाएं लोड की जाती हैं तो JLS, Section 12.4.1 द्वारा कवर किया जाता है।

एक वर्ग या इंटरफ़ेस प्रकार टी निम्नलिखित में से किसी एक की पहली आवृत्ति से ठीक पहले प्रारंभ किया जाएगा:

  • टी एक वर्ग और टी का एक उदाहरण बनाया जाता है।

  • टी एक वर्ग है और टी द्वारा घोषित एक स्थिर विधि का आह्वान किया जाता है।

  • टी द्वारा घोषित एक स्थिर क्षेत्र असाइन किया गया है।

  • टी द्वारा घोषित एक स्थिर क्षेत्र का उपयोग किया जाता है और फ़ील्ड निरंतर परिवर्तनीय नहीं है (§4.12.4)।

  • टी एक शीर्ष स्तर की कक्षा (§7.6) है, और एक जोरदार कथन (§14.10) टी (§8.1.3) के भीतर निहित रूप से घिरा हुआ है।

(कटाव)

एक वर्ग या इंटरफ़ेस किसी अन्य परिस्थिति में आरंभ नहीं किया जा जाएगा।

Chapter 5 कक्षाओं को लोड करने, जोड़ने और प्रारंभ करने के बारे में वार्ता।

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

आपका प्रश्न:

  1. एक चर घोषणा वर्ग लोड नहीं करता है। लेकिन लोडिंग से पहले लोडिंग होती है, और प्रारंभ करने से पहले लिंकिंग होता है। इसलिए, जब एक वर्ग लोड होता है, तब भी इसे जोड़ा और प्रारंभ किया जाता है।
  2. Integer कक्षा आपके कोड चलाने से पहले JVM (कई अन्य भाषा नींव वर्गों के साथ) द्वारा लोड की जाती है।
  3. अब Test कक्षा लोड की गई है, क्योंकि एक नया उदाहरण बनाया गया है।
  4. Test4 लोड नहीं किया गया था, क्योंकि केवल एक स्थिर चर का उपयोग किया गया था, जो ऊपर के चौथे नियम के साथ संघर्ष करता है। क्योंकि Test2 वस्तुओं Test के उदाहरण प्रारंभकर्ता है, जो भी Test3 वजह से (सुपर क्लास) लोड करने के लिए में बनाया गया
  5. Test3 और Test2, के बाद Test लोड किया गया था भेजा गया।

यह पुष्टि की जाती है कि running your code with the JVM option -verbose:class

+0

यह नोट करना कि प्रारंभ करना लोडिंग (या लिंकिंग) जैसा नहीं है। –

+0

यदि ** टेस्ट ** कक्षा लाइन (1) पर लोड नहीं होती है तो किस प्रकार परिवर्तनीय ** टी ** होगा? –

+0

JVM में, चर 't' अभी तक मौजूद नहीं होगा; यह अभी तक आवंटित नहीं है। – rgettman

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

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