जावा 8 लैम्बडा एक्सप्रेशंस जैसी महत्वपूर्ण नई भाषा सुविधाएँ पेश करता है।
क्या भाषा में ये परिवर्तन संकलित बायटेकोड में ऐसे महत्वपूर्ण परिवर्तनों के साथ हैं जो इसे कुछ रेट्रोट्रांसलेटर का उपयोग किए बिना जावा 7 वर्चुअल मशीन पर चलने से रोकेंगे?
जावा 8 लैम्बडा एक्सप्रेशंस जैसी महत्वपूर्ण नई भाषा सुविधाएँ पेश करता है।
क्या भाषा में ये परिवर्तन संकलित बायटेकोड में ऐसे महत्वपूर्ण परिवर्तनों के साथ हैं जो इसे कुछ रेट्रोट्रांसलेटर का उपयोग किए बिना जावा 7 वर्चुअल मशीन पर चलने से रोकेंगे?
जवाबों:
नहीं, आपके स्रोत कोड में 1.8 सुविधाओं का उपयोग करने के लिए आपको 1.8 वीएम को लक्षित करने की आवश्यकता होती है। मैंने अभी-अभी नया जावा 8 रिलीज़ करने की कोशिश की और संकलन करने की कोशिश की -target 1.7 -source 1.8
, और कंपाइलर ने मना कर दिया:
$ javac Test -source 1.8 -target 1.7
javac: source release 1.8 requires target release 1.8
डिफ़ॉल्ट तरीकों को बाईटेकोड और जेवीएम में ऐसे बदलावों की आवश्यकता होती है जो उन्हें जावा 7 पर करना असंभव हो जाता है। जावा 7 और उससे नीचे के बायोटेक वेरिफायर मेथड बॉडीज के साथ इंटरफेस को रिजेक्ट कर देंगे (स्टैटिक इनिशियलाइजर विधि को छोड़कर) कॉल करने वाले की ओर से स्थिर विधियों के साथ डिफ़ॉल्ट विधियों का अनुकरण करने की कोशिश करने से परिणाम समान नहीं होंगे, क्योंकि उपवर्गों में डिफ़ॉल्ट विधियों को ओवरराइड किया जा सकता है। रेट्रोलंबा के पास डिफ़ॉल्ट तरीकों को बैकपोर्ट करने के लिए सीमित समर्थन है, लेकिन इसे कभी भी पूरी तरह से वापस नहीं लाया जा सकता है क्योंकि इसके लिए वास्तव में नए जेवीएम सुविधाओं की आवश्यकता होती है।
लैम्ब्डा जावा 7 पर चल सकता है, यदि आवश्यक एपीआई कक्षाएं बस वहां मौजूद होंगी। जावा 7 पर इनवॉकेन्डेमिक निर्देश मौजूद है, लेकिन लैम्बडा को लागू करना संभव होगा, ताकि यह संकलित समय पर लैम्ब्डा कक्षाएं उत्पन्न करता है (प्रारंभिक जेडीके 8 बिल्ड्स ने इसे इस तरह से बनाया) जिस स्थिति में यह किसी भी जावा संस्करण के लिए काम करेगा। (ओरेकल ने भविष्य के अशुद्धि जाँच के लिए लैम्ब्डा के लिए इनवॉकेन्डेक्टिक का उपयोग करने का निर्णय लिया; हो सकता है कि एक दिन जेवीएम में प्रथम श्रेणी के कार्य होंगे, इसलिए तब प्रत्येक लैम्ब्डा के लिए एक क्लास उत्पन्न करने के बजाय उन्हें उपयोग करने के लिए इनवॉकेन्डेमिक को बदला जा सकता है, इस प्रकार प्रदर्शन)। यह उन सभी चालित निर्देश को संसाधित करता है और उन्हें अनाम कक्षाओं के साथ बदल देता है; जब जावा लैम्बा द्वारा आह्वान किया जाता है तो जावा 8 रनटाइम के दौरान पहली बार कहा जाता है।
बार-बार एनोटेशन करना सिंटैक्टिक शुगर है। वे पिछले संस्करणों के साथ संगत बायटेकोड हैं। जावा 7 में आपको बस अपने आप को सहायक विधियों (जैसे getAnnotationsByType ) को लागू करने की आवश्यकता होगी, जो कंटेनर एनोटेशन के कार्यान्वयन विवरण को छिपाते हैं जिसमें बार-बार एनोटेशन होते हैं।
AFAIK, टाइप एनोटेशन केवल संकलित समय पर मौजूद होते हैं, इसलिए उन्हें bytecode परिवर्तनों की आवश्यकता नहीं होनी चाहिए, इसलिए केवल Java 7 पर काम करने के लिए Java 8-संकलित कक्षाओं के बाईटेककोड संस्करण संख्या को बदलना पर्याप्त होना चाहिए।
विधि पैरामीटर नाम मौजूद हैं बाइटकोड में जावा 7 के साथ, इसलिए यह भी संगत है। आप विधि के बाईटकोड को पढ़कर और विधि के डिबग जानकारी में स्थानीय चर नामों को देखकर उन तक पहुंच प्राप्त कर सकते हैं। उदाहरण के लिए, स्प्रिंग फ्रेमवर्क वास्तव में @PathVariable को लागू करने के लिए करता है , इसलिए संभवतः एक पुस्तकालय विधि है जिसे आप कॉल कर सकते हैं। क्योंकि एब्सट्रैक्ट इंटरफ़ेस मेथड्स में एक बॉडी नहीं होती है, लेकिन डीबग जानकारी जावा 7 में इंटरफ़ेस मेथड के लिए मौजूद नहीं है, और AFAIK न ही जावा 8 पर।
अन्य नई सुविधाओं में ज्यादातर नए एपीआई, हॉटस्पॉट और टूलिंग में सुधार हैं। नए API में से कुछ 3rd पार्टी लाइब्रेरी (उदाहरण के लिए थ्रीटीन-बैकपोर्ट और स्ट्रीमअप ) के रूप में उपलब्ध हैं।
सुम्मा सारांश, डिफ़ॉल्ट विधियों में नई JVM सुविधाओं की आवश्यकता होती है, लेकिन अन्य भाषा सुविधाएँ नहीं होती हैं। यदि आप उनका उपयोग करना चाहते हैं, तो आपको जावा 8 में कोड संकलित करने की आवश्यकता होगी और फिर बाईट्रोड को रेट्रालंबा के साथ जावा 5/6/7 प्रारूप में बदलना होगा । कम से कम बायटेकोड संस्करण को बदलने की जरूरत है, और -source 1.8 -target 1.7
जेवैक को रोकना है ताकि एक रेट्रोट्रांसलेटर की आवश्यकता हो।
जहाँ तक मुझे पता है कि JDK 8 में इन परिवर्तनों में से किसी को भी नए बायोटेक के अतिरिक्त की आवश्यकता नहीं थी। लैम्ब्डा इंस्ट्रूमेंटेशन का एक हिस्सा उपयोग किया जा रहा है invokeDynamic
(जो पहले से ही जेडीके 7 में मौजूद है)। इसलिए, जेवीएम इंस्ट्रक्शन सेट के दृष्टिकोण से, कुछ भी कोडबेस को असंगत नहीं बनाना चाहिए। हालाँकि, बहुत सारे एपीआई से जुड़े और कंपाइलर सुधार हैं जो कि जेडीके 8 से कोड को पिछले जेडीके के तहत संकलन / चलाने में मुश्किल बना सकते हैं (लेकिन मैंने यह कोशिश नहीं की है)।
हो सकता है कि निम्नलिखित संदर्भ सामग्री किसी तरह से यह समझने में मदद कर सके कि लैम्ब्डा से संबंधित परिवर्तन कैसे किए जा रहे हैं।
ये विस्तार से बताते हैं कि कैसे हुड के तहत चीजें होती हैं। शायद आप अपने सवालों का जवाब वहां पा सकते हैं।
class C extends A with B
, सामान्य इंटरफेस के साथ लागू किया गया है A
और B
और साथी वर्गों A$class
और B$class
। क्लास C
केवल आगे की ओर स्टैटिक साथी क्लासेस की विधियाँ। स्व-प्रकार बिल्कुल लागू नहीं होते हैं, लैम्बदास को सार-समय पर अमूर्त आंतरिक कक्षाओं में स्थानांतरित किया जाता है, इसलिए यह एक new D with A with B
अभिव्यक्ति है। पैटर्न-मिलान अगर-और संरचनाओं का एक गुच्छा है। गैर-स्थानीय रिटर्न? लैम्ब्डा से तंत्र को पकड़ने की कोशिश। कुछ भी बचा है? (दिलचस्प है, मेरी खोपड़ी कहती है कि 1.6 डिफ़ॉल्ट है)
यदि आप एक "रेट्रोट्रांसलेटर" का उपयोग करने के लिए तैयार हैं, तो एस्को लुओंटोला के उत्कृष्ट रेट्रोलंबा की कोशिश करें : https://github.com/orfjackal/retrolambda