2010-01-27 12 views
7

जावा में, संकलन पर हमें स्रोत फ़ाइल में परिभाषित प्रत्येक वर्ग (नेस्टेड कक्षाओं और इंटरफेस सहित) के लिए .class फ़ाइल प्राप्त होती है।

इस एकाधिक .class फ़ाइल पीढ़ी का कारण क्या है?
क्या कक्षा की पुन: उपयोगिता को सरल बनाने के लिए है?
एक .java फ़ाइल के लिए एक .class क्यों उत्पन्न नहीं करें?जावा संकलन पर एकाधिक .class फ़ाइलों को क्यों उत्पन्न करता है?

+0

तथ्य यह है कि 1 जावा क्लास बिल्कुल 1 .class फ़ाइल में संग्रहीत है और वह 1 .class फ़ाइल में बिल्कुल 1 वर्ग है (वास्तव में, यह एक इंटरफेस, एनोटेशन प्रकार या एनम भी हो सकता है) हैंडलिंग और लोडिंग को सरल बनाता है कक्षाओं और .class दोनों फाइलों के। –

उत्तर

7

@Jon स्कीट की बयानबाजी प्रश्न के उत्तर में:

एक अन्य वर्ग तो, बार को संदर्भित करता है तो JVM इसके लिए कोड की जरूरत है ... आप इसे फ़ाइल पाता कैसे सुझाव है?

मान लीजिए कि जावा क्लासफ़ाइल प्रारूप ने बाहरीतम वर्ग के लिए क्लासफ़ाइल में एम्बेड करके नेस्टेड/आंतरिक कक्षाओं का प्रतिनिधित्व किया है। बार के लिए बाइनरी नाम "Lsome/pkg/Foo$Bar;" है। वर्ग लोडर "$" वर्ण पर नाम विभाजित कर सकता है, Foo के लिए क्लासफ़ाइल का पता लगाने के लिए पहले भाग का उपयोग करें, और उसके बाद एम्बेडेड बार क्लास प्रतिनिधित्व पर नेविगेट करें।

मुझे लगता है कि असली कारण है कि आंतरिक/घोंसले वाले वर्गों में अलग-अलग क्लासफाइल ऐतिहासिक हैं। आईआईआरसी, जावा 1.0 ने नेस्टेड या आंतरिक कक्षाओं का समर्थन नहीं किया, और इसलिए संबंधित क्लासफाइल स्वरूपों को उनके साथ सौदा करने की आवश्यकता नहीं थी। जब जावा 1.1 बनाया गया था (आंतरिक/नेस्टेड कक्षाओं का समर्थन), सूर्य चाहता था कि क्लासफ़ाइल प्रारूप जावा 1.0 कंपाइलर द्वारा उत्पादित क्लासफ़ाइल के साथ संगत हो। इसलिए उन्होंने बाइनरी क्लासनाम में आरक्षित "$" चरित्र का उपयोग करके आंतरिक कक्षाओं के रूप में आंतरिक/नेस्टेड कक्षाओं को लागू करना चुना।

एक दूसरा संभावित कारण यह है कि फ्लैट प्रारूप एक hypothetical एम्बेडेड प्रारूप की तुलना में वर्ग लोडिंग को सरल बनाता है।

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

+0

अंतिम पैराग्राफ स्पॉट पर है, मुझे लगता है। जावा * पहले से * में एक कंटेनर प्रारूप है जो एकाधिक वर्गों (और संसाधनों) को एक फ़ाइल में बंडल कर सकता है। एक ही सुविधा को एक और स्तर पर क्यों पेश करें? –

12

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

उदाहरण के रूप में: मान लीजिए कि मैं Foo.java संकलित करना था जिसमें कक्षा बार शामिल है।

तब एक और वर्ग बार को संदर्भित करता है, इसलिए JVM को इसके लिए कोड की आवश्यकता होती है ... आप कैसे सुझाव देंगे कि यह फ़ाइल पाता है?

नोट .NET में यह है कि तैनाती की इकाई का एक अलग विधानसभा कहा जाता है - और एक प्रकार के लिए एक संदर्भ विधानसभा नाम के रूप में अच्छी तरह से शामिल है, लेकिन यह है कि आप क्या प्रस्ताव कर रहे थे से थोड़ा अलग है।

2

डेवलपर्स द्वारा बनाई गई संकलन इकाई के संबंध में यह एक डिज़ाइन निर्णय है। संकलित कक्षाएं आमतौर पर एक जार फ़ाइल में संयुक्त होती हैं।

Java Language Spec

7,3 संकलन इकाइयों से

निकालें CompilationUnit जावा कार्यक्रमों के वाक्यात्मक व्याकरण (§2.3) के लिए लक्ष्य प्रतीक (§2.1) है।

विभिन्न संकलन इकाइयों में घोषित प्रकार एक दूसरे पर, परिपत्र पर निर्भर कर सकते हैं। एक जावा कंपाइलर को एक ही समय में ऐसे सभी प्रकारों को संकलित करने की व्यवस्था करनी होगी।

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