2010-11-24 19 views

उत्तर

18

संकलक (समय निर्भरता संकलन)

JVM क्रम पुस्तकालय में कक्षाएं आप बुला रहे हैं (क्रम निर्भरता) लोड करने में सही classpath की जरूरत है, ताकि एक पुस्तकालय के लिए कॉल को संकलित करने में सही classpath की जरूरत है।

वे कई तरीकों से में अलग हो सकता है:)

1 अगर अपनी कक्षा सी 1 पुस्तकालय वर्ग एल 1 कहता है, और एल 1 कॉल पुस्तकालय वर्ग एल 2, तो सी 1 L1 और L2 पर एक क्रम निर्भरता है, लेकिन केवल एक एल 1 पर संकलन समय निर्भरता।

2) यदि आपकी कक्षा सी 1 गतिशील रूप से कक्षा.forName() या किसी अन्य तंत्र का उपयोग कर इंटरफ़ेस I1 को गतिशील करता है, और इंटरफ़ेस I1 के लिए कार्यान्वयन वर्ग कक्षा L1 है, तो C1 में I1 और L1 पर रनटाइम निर्भरता है, लेकिन केवल I1 पर एक संकलन समय निर्भरता।

अन्य "अप्रत्यक्ष" निर्भरता जो संकलन समय के लिए ही कर रहे हैं और रन-टाइम:

3) अपने वर्ग सी 1 फैली पुस्तकालय वर्ग एल 1, और एल 1 इंटरफेस I1 लागू करता है और पुस्तकालय वर्ग एल 2 लागू होता है: सी 1 एक है एल 1, एल 2, और आई 1 पर संकलन-समय निर्भरता।

4) अपने वर्ग सी 1 एक विधि foo(I1 i1) और एक विधि bar(L1 l1) जहां I1 एक अंतरफलक है और एल 1 एक वर्ग है कि एक पैरामीटर जो इंटरफेस I1 है लेता है: सी 1 I1 और एल 1 पर एक संकलन समय निर्भरता है।

मूल रूप से, कुछ भी दिलचस्प करने के लिए, कक्षा को कक्षाओं में अन्य वर्गों और इंटरफेस के साथ इंटरफ़ेस की आवश्यकता होती है। पुस्तकालय इंटरफेस के उस सेट द्वारा गठित वर्ग/इंटरफेस ग्राफ संकलन-समय निर्भरता श्रृंखला उत्पन्न करता है। पुस्तकालय कार्यान्वयन रन-टाइम निर्भरता श्रृंखला उत्पन्न करते हैं। ध्यान दें कि रन-टाइम निर्भरता श्रृंखला रन-टाइम निर्भर या असफल-धीमी है: यदि एल 1 का कार्यान्वयन कभी-कभी कक्षा L2 के किसी ऑब्जेक्ट को तुरंत चालू करने पर निर्भर करता है, और वह वर्ग केवल एक विशेष परिदृश्य में तत्काल हो जाता है, तो कोई निर्भरता नहीं है उस परिदृश्य में।

+0

उदाहरण में 1 संकलन समय पर संकलन निर्भरता नहीं होना चाहिए? – BalusC

+0

yup, कुछ टाइपो तय किए गए। –

+0

धन्यवाद, लेकिन कक्षा लोडिंग रन टाइम पर कैसे काम करती है? संकलन समय पर समझना आसान है। लेकिन रनटाइम पर, यह कैसे काम करता है, ऐसे मामले में जब मेरे पास अलग-अलग संस्करणों के दो जार हैं? यह कौन सा उठाएगा? – Kunal

10

जावा वास्तव में संकलन समय पर कुछ भी लिंक नहीं करता है। यह केवल क्लासस्पैट में मिलने वाली मिलान कक्षाओं का उपयोग करके सिंटैक्स को सत्यापित करता है। यह रनटाइम तक नहीं है कि उस समय क्लासस्पैट के आधार पर सबकुछ एक साथ रखा जाता है और निष्पादित किया जाता है।

9

संकलन समय निर्भरता केवल निर्भरता (अन्य कक्षाएं) हैं जिन्हें आप संकलित कर रहे वर्ग में सीधे का उपयोग करते हैं। रनटाइम निर्भरताएं आपके द्वारा चलाए जा रहे वर्ग की प्रत्यक्ष और अप्रत्यक्ष निर्भरताओं दोनों को शामिल करती हैं। इस प्रकार, रनटाइम निर्भरताओं में निर्भरता की निर्भरताएं और किसी भी प्रतिबिंब निर्भरताएं जैसे वर्गनाम जो आपके पास String में हैं, लेकिन Class#forName() में उपयोग किए जाते हैं।

+0

धन्यवाद, लेकिन कैसे रन टाइम पर क्लास लोडिंग काम? संकलन समय पर समझना आसान है। लेकिन रनटाइम पर, यह कैसे काम करता है, जब मेरे पास अलग-अलग संस्करणों के दो जार होते हैं? कौन सा वर्ग क्लास.forनाम() पिकअप के मामले में होगा कई कक्षाएं एक वर्ग पथ में विभिन्न वर्गों के? – Kunal

+0

पाठ्यक्रम के नाम से मेल खाता है। यदि आप * वास्तव में * एक ही कक्षा के कई संस्करणों का मतलब है, तो यह क्लासलोडर पर निर्भर करता है। "निकटतम" लोड किया जाएगा। – BalusC

+0

खैर मुझे लगता है कि अगर आपके पास ए 'ए' के ​​साथ एजर है, तो बी 'बी' के साथ बी 'ए' बढ़ाता है और सी सी के साथ सी सी बढ़ाता है तो सीजर एजर पर संकलन समय पर निर्भर करता है, भले ही सी निर्भरता ए पर अप्रत्यक्ष है। – gpeche

22

एक आसान उदाहरण है servi api की तरह एपीआई को देखना। अपने सर्वलेट को संकलित करने के लिए, आपको servlet-api.jar की आवश्यकता है, लेकिन रनटाइम पर सर्वलेट कंटेनर एक सर्वलेट एपीआई कार्यान्वयन प्रदान करता है, इसलिए आपको अपने रनटाइम क्लास पथ में servlet-api.jar जोड़ने की आवश्यकता नहीं है।

+0

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

+1

'प्रदत्त' का अर्थ है, संकलन समय में शामिल करें, लेकिन इसे WAR या निर्भरता के अन्य संग्रह में बंडल न करें। 'रनटाइम' विपरीत है (संकलन पर उपलब्ध नहीं है, लेकिन WAR के साथ पैक किया गया है)। –

50
  • संकलन समय निर्भरता: आप अपने विरूपण साक्ष्य संकलित करने के लिए अपने CLASSPATH में निर्भरता की जरूरत है। वे उत्पादित होते हैं क्योंकि आपके पास कुछ कोड के लिए new को कॉल करने, किसी भी वर्ग के लिए new को कॉल करने, या तो प्रत्यक्ष या अप्रत्यक्ष रूप से लागू करने या सीधे reference.method() नोटेशन का उपयोग करके एक विधि कॉल को लागू करने के लिए आपके कोड में हार्डकोडेड निर्भरता के लिए कुछ प्रकार का "संदर्भ" है।

  • रन-समय निर्भरता: आप अपने CLASSPATH में निर्भरता अपने विरूपण साक्ष्य को चलाने के लिए की जरूरत है। वे उत्पादित होते हैं क्योंकि आप उस कोड को निष्पादित करते हैं जो निर्भरता तक पहुंचता है (या तो हार्डकोडेड तरीके से या प्रतिबिंब या जो भी हो)।

हालांकि संकलन समय निर्भरता आमतौर पर रन-टाइम निर्भरता का अर्थ है, आप केवल निर्भरता एक संकलन समय हो सकता है। यह इस तथ्य पर आधारित है कि जावा केवल उस वर्ग की पहली पहुंच पर क्लास निर्भरता को लिंक करता है, इसलिए यदि आप रन-टाइम पर किसी विशेष श्रेणी तक कभी भी पहुंच नहीं पाते हैं क्योंकि कोड पथ कभी नहीं चलाया जाता है, तो जावा कक्षा और इसकी निर्भरताओं दोनों को अनदेखा कर देगा।

इस

C.java में का उदाहरण (C.class उत्पन्न करता है):

package dependencies; 
public class C { } 

A.java में (उत्पन्न A.class):

package dependencies; 
public class A { 
    public static class B { 
     public String toString() { 
      C c = new C(); 
      return c.toString(); 
     } 
    } 
    public static void main(String[] args) { 
     if (args.length > 0) { 
      B b = new B(); 
      System.out.println(b.toString()); 
     } 
    } 
} 

इस मामले में , A में C पर B पर संकलन-समय निर्भरता है, लेकिन अगरनिष्पादित करते समय आप कुछ पैरामीटर पास करते हैं तो इसकी सी पर केवल रन-टाइम निर्भरता होगी, क्योंकि JVM केवल निष्पादित करने पर C पर B की निर्भरता को हल करने का प्रयास करेगा। यह सुविधा आपको रनटाइम पर केवल उन वर्गों की निर्भरता प्रदान करने की अनुमति देती है जिन्हें आप अपने कोड पथ में उपयोग करते हैं, और आर्टिफैक्ट में शेष वर्गों की निर्भरताओं को अनदेखा करते हैं।

1

जावा के लिए, संकलन समय निर्भरता आपके स्रोत कोड की निर्भरता है। उदाहरण के लिए, यदि कक्षा ए कक्षा बी से एक विधि कहता है, तो ए संकलन समय पर बी पर निर्भर है क्योंकि ए को संकलित करने के लिए बी (प्रकार बी) के बारे में पता होना चाहिए। यह चाल यहां होनी चाहिए: संकलित कोड अभी तक एक पूर्ण और निष्पादन योग्य कोड नहीं है। इसमें उन स्रोतों के लिए प्रतिस्थापन योग्य पते (प्रतीकों, मेटाडेटा) शामिल हैं जो अभी तक संकलित नहीं हैं या बाहरी जार में मौजूद नहीं हैं। लिंकिंग के दौरान, उन पते को स्मृति में वास्तविक पते द्वारा प्रतिस्थापित किया जाना चाहिए। इसे सही तरीके से करने के लिए, सही प्रतीक/पते तैयार किए जाने चाहिए। और यह कक्षा के प्रकार (बी) के साथ किया जा सकता है। मुझे विश्वास है कि संकलन समय पर मुख्य निर्भरता है।

रनटाइम निर्भरता वास्तविक प्रवाह-नियंत्रण से अधिक संबंधित है। यह वास्तविक स्मृति पते का आह्वान करता है। यह एक निर्भरता है कि आपका प्रोग्राम चल रहा है जब आपके पास है। आपको कक्षा बी विवरणों को कार्यान्वयन की तरह यहां चाहिए, न केवल प्रकार की जानकारी। यदि वर्ग मौजूद नहीं है, तो आपको RuntimeException मिलेगा और JVM बाहर निकल जाएगा।

दोनों निर्भरताएं, आम तौर पर और नहीं, एक ही दिशा में बहती हैं। हालांकि यह ओओ डिजाइन का मामला है।

सी ++ में, संकलन थोड़ा अलग है (केवल समय में नहीं) लेकिन इसमें एक लिंकर भी है। इसलिए प्रक्रिया को जावा के अनुमान के समान माना जा सकता है।

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