जावा में संकलित समय और रन समय निर्भरता के बीच अंतर क्या है? यह वर्ग पथ से संबंधित है, लेकिन वे कैसे भिन्न हैं?
जवाबों:
संकलन-समय निर्भरता : आपको CLASSPATH
अपनी कलाकृतियों को संकलित करने के लिए निर्भरता की आवश्यकता है। वे उत्पादित होते हैं क्योंकि आपके पास कोड में किसी प्रकार की निर्भरता हार्डकोड करने के लिए "संदर्भ" होता है, जैसे कि new
कुछ वर्ग के लिए कॉल करना , किसी चीज़ का विस्तार करना या लागू करना (या तो प्रत्यक्ष या अप्रत्यक्ष रूप से), या डायरेक्ट reference.method()
नोटेशन का उपयोग करके एक विधि कॉल ।
रन-टाइम निर्भरता : CLASSPATH
अपनी कलाकृतियों को चलाने के लिए आपको अपनी निर्भरता की आवश्यकता होती है। वे उत्पादित होते हैं क्योंकि आप कोड को निष्पादित करते हैं जो निर्भरता तक पहुंचता है (या तो हार्डकोड तरीके से या प्रतिबिंब के माध्यम से या जो भी)।
यद्यपि संकलन-समय निर्भरता आमतौर पर रन-टाइम निर्भरता का अर्थ है, आपके पास केवल संकलन-समय निर्भरता हो सकती है। यह इस तथ्य पर आधारित है कि जावा केवल उस वर्ग तक पहली पहुंच पर वर्ग निर्भरता को जोड़ता है, इसलिए यदि आप रन-टाइम पर किसी विशेष वर्ग तक कभी नहीं पहुंचते हैं क्योंकि एक कोड पथ कभी नहीं निकाला जाता है, तो जावा वर्ग और उसकी निर्भरता दोनों को अनदेखा करेगा।
इसका उदाहरण है
C.java में (C.class उत्पन्न करता है):
package dependencies;
public class C { }
अजावा में (ए। अकास उत्पन्न करता है):
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 पर एक रन-टाइम निर्भरता है यदि आप निष्पादित करते समय कुछ पैरामीटर पास करते हैं , क्योंकि JVM केवल निष्पादित होने पर निर्भरता को हल करने का प्रयास करेगा। । यह सुविधा आपको रनटाइम पर केवल उन वर्गों की निर्भरता प्रदान करने की अनुमति देती है जो आप अपने कोड पथों में उपयोग करते हैं, और कलाकृतियों में बाकी कक्षाओं की निर्भरता को अनदेखा करते हैं।C
B
java dependencies.A
B
C
B b = new B()
एक आसान उदाहरण सर्वलेट एपी की तरह एक एपी को देखना है। अपने सर्वलेट्स को संकलित करने के लिए, आपको सर्वलेट-एपी.जर की आवश्यकता है, लेकिन रनटाइम के दौरान सर्वलेट कंटेनर एक सर्वलेट एपि कार्यान्वयन प्रदान करता है, इसलिए आपको अपने रनटाइम क्लास पथ में सर्वलेट-एपी.जर जोड़ने की आवश्यकता नहीं है।
संकलक को लाइब्रेरी में कॉल संकलित करने के लिए सही क्लासपाथ की आवश्यकता होती है (संकलन समय निर्भरता)
जिस लाइब्रेरी को आप कॉल कर रहे हैं (रनटाइम डिपेंडेंसी), उस क्लास में लोड करने के लिए जेवीएम को सही क्लासपैथ की जरूरत होती है।
वे कुछ तरीकों से भिन्न हो सकते हैं:
1) अगर आपकी क्लास C1 लाइब्रेरी क्लास L1 कहती है, और L1 लाइब्रेरी क्लास L2 कहती है, तो C1 में L1 और L2 पर रनटाइम डिपेंडेंसी है, लेकिन L1 पर केवल एक संकलन समय निर्भरता है।
2) यदि आपकी कक्षा C1 डायनामिक रूप से I1 को Class.forName () या कुछ अन्य तंत्र का उपयोग करती है, और इंटरफ़ेस I1 के लिए कार्यान्वयन वर्ग क्लास L1 है, तो C1 में I1 और L1 पर रनटाइम निर्भरता है, लेकिन केवल एक संकलन समय निर्भरता है। I1 पर।
अन्य "अप्रत्यक्ष" निर्भरताएं जो संकलन-समय और रन-टाइम के लिए समान हैं:
3) आपकी क्लास C1 लाइब्रेरी क्लास L1 तक फैली हुई है, और L1 इम्प्रूवमेंट इंटरफ़ेस I1 का विस्तार करती है और लाइब्रेरी क्लास L2 का विस्तार करती है: C1 में L1, L2 और I1 पर एक कंपाइल-टाइम डिपेंडेंसी है।
4) आपके वर्ग C1 में एक विधि foo(I1 i1)
और एक विधि है bar(L1 l1)
जहाँ I1 एक इंटरफ़ेस है और L1 एक वर्ग है जो एक पैरामीटर लेता है जो इंटरफ़ेस I1 है: C1 में I1 और L1 पर एक संकलन-समय निर्भरता है।
मूल रूप से, कुछ भी दिलचस्प करने के लिए, आपकी कक्षा को अन्य कक्षाओं और इंटरफ़ेस के साथ क्लासपैथ में इंटरफ़ेस करने की आवश्यकता होती है। लाइब्रेरी इंटरफेस के उस सेट द्वारा गठित क्लास / इंटरफ़ेस ग्राफ , संकलन-समय निर्भरता श्रृंखला की उपज देता है। पुस्तकालय कार्यान्वयन रन-टाइम निर्भरता श्रृंखला उपजते हैं। ध्यान दें कि रन-टाइम डिपेंडेंसी चेन रन-टाइम डिपेंडेंट या फेल-स्लो है: यदि L1 का कार्यान्वयन कभी-कभी क्लास L2 के ऑब्जेक्ट को इंस्टेंटिमिट करने पर निर्भर करता है, और वह क्लास केवल एक विशेष परिदृश्य में तुरंत हो जाती है, तो इसके अलावा कोई भरोसेमंद संभावना नहीं है वह परिदृश्य।
जावा वास्तव में संकलन समय पर कुछ भी लिंक नहीं करता है। यह केवल उन मिलान वर्गों का उपयोग करके सिंटैक्स की पुष्टि करता है जो इसे CLASSPATH में पाता है। यह रनटाइम तक नहीं है कि सब कुछ एक साथ रखा जाता है और उस समय CLASSPATH के आधार पर निष्पादित होता है।
कंपाइलटाइम निर्भरता केवल निर्भरता (अन्य कक्षाएं) हैं जो आप उस कक्षा में सीधे उपयोग करते हैं जिसे आप संकलित कर रहे हैं। रनटाइम निर्भरताएँ आपके द्वारा चलाए जा रहे वर्ग की प्रत्यक्ष और अप्रत्यक्ष निर्भरता दोनों को कवर करती हैं। इस प्रकार, रनटाइम निर्भरता में निर्भरता की निर्भरता और किसी भी प्रतिबिंब पर निर्भरता जैसे क्लासनाम शामिल हैं जो आपके पास है String
, लेकिन इसमें उपयोग किया जाता है Class#forName()
।
A
, B.jar with B extends A
और C.jar है C extends B
तो C.jar का संकलन समय पर निर्भर करता है, जबकि A पर C निर्भरता अप्रत्यक्ष है।
जावा के लिए, संकलन समय निर्भरता आपके स्रोत कोड की निर्भरता है। उदाहरण के लिए, यदि वर्ग A वर्ग B से एक विधि कहता है, तो A, संकलन समय पर B पर निर्भर है क्योंकि A को B के प्रकार (B के प्रकार) के बारे में जानना है। यहाँ चाल यह होनी चाहिए: संकलित कोड अभी तक एक पूर्ण और निष्पादन योग्य कोड नहीं है। इसमें उन स्रोतों के लिए बदली पते (प्रतीक, मेटाडेटा) शामिल हैं, जो अभी तक बाहरी जार में संकलित या विद्यमान नहीं हैं। लिंक करने के दौरान, उन पतों को स्मृति में वास्तविक एड्रेसेस द्वारा प्रतिस्थापित किया जाना चाहिए। इसे ठीक से करने के लिए, सही प्रतीकों / आदतों का निर्माण किया जाना चाहिए। और यह वर्ग (बी) के प्रकार के साथ किया जा सकता है। मेरा मानना है कि संकलन के समय मुख्य निर्भरता है।
रनटाइम निर्भरता वास्तविक प्रवाह-नियंत्रण से अधिक संबंधित है। यह वास्तविक मेमोरी पतों पर आक्रमण करता है। यह एक निर्भरता है जो आपके पास है जब आपका कार्यक्रम चल रहा है। आपको यहां क्लास बी विवरण की आवश्यकता है जैसे कि कार्यान्वयन, न केवल प्रकार की जानकारी। यदि वर्ग मौजूद नहीं है, तो आपको RuntimeException मिल जाएगी और JVM बाहर निकल जाएगा।
दोनों निर्भरता, आम तौर पर और एक ही दिशा में प्रवाह नहीं होना चाहिए। यह हालांकि OO डिजाइन का मामला है।
C ++ में, संकलन थोड़ा अलग है (सिर्फ-इन-टाइम नहीं), लेकिन इसमें एक लिंकर भी है। तो इस प्रक्रिया को जावा I अनुमान के समान माना जा सकता है।