जावा 8 कोड को जावा 7 जेवीएम पर चलाने के लिए संकलित किया जा सकता है?


163

जावा 8 लैम्बडा एक्सप्रेशंस जैसी महत्वपूर्ण नई भाषा सुविधाएँ पेश करता है।

क्या भाषा में ये परिवर्तन संकलित बायटेकोड में ऐसे महत्वपूर्ण परिवर्तनों के साथ हैं जो इसे कुछ रेट्रोट्रांसलेटर का उपयोग किए बिना जावा 7 वर्चुअल मशीन पर चलने से रोकेंगे?


जवाबों:


146

नहीं, आपके स्रोत कोड में 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

4
नहीं, मुझे नहीं लगता कि यह होगा। जावा के पास डेस्कटॉप बाजार का एक छोटा हिस्सा है, लेकिन उस छोटे हिस्से को काफी तंग पकड़ में रखता है। लेकिन यह नए संस्करणों और सुविधाओं को अपनाने में बाधा डालता है। मैं काफी समय से अपने द्वारा लिखे गए कोड में जावा 8 सुविधाओं का उपयोग नहीं कर पाऊंगा, क्योंकि मैं उन लोगों से बचना चाहता हूं जो अपने मोबाइल जावा इंस्टॉलेशन को अपग्रेड करने से बचते हैं।
जेस्पर

क्यों? "हां" का अर्थ होगा कि जावा 8 को जावा 7 वीएम पर चलाने के लिए संकलित किया जा सकता है, जो कि जावा 8 कंपाइलर के अनुसार गलत है।
जेसपेई

5
अब मैं देखता हूं: आपका "नहीं" प्रश्न के शीर्षक का उत्तर देता है, प्रश्न के शरीर का नहीं।
अब्दुल

58

डिफ़ॉल्ट तरीकों को बाईटेकोड और जेवीएम में ऐसे बदलावों की आवश्यकता होती है जो उन्हें जावा 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जेवैक को रोकना है ताकि एक रेट्रोट्रांसलेटर की आवश्यकता हो।


3
वास्तव में टाइप एनोटेशन रनटाइम दिखाई दे सकते हैं। stackoverflow.com/questions/22374612/…
प्रतिमा

33

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

हो सकता है कि निम्नलिखित संदर्भ सामग्री किसी तरह से यह समझने में मदद कर सके कि लैम्ब्डा से संबंधित परिवर्तन कैसे किए जा रहे हैं।

ये विस्तार से बताते हैं कि कैसे हुड के तहत चीजें होती हैं। शायद आप अपने सवालों का जवाब वहां पा सकते हैं।


7
कोई नया बायटेकोड नहीं, बल्कि नई संरचनाएं। सत्यापनकर्ता पुक करेगा।
जोनाथन एस। फिशर

12
एक अच्छा उदाहरण इंटरफेसेस है। वे अब तरीके शामिल कर सकते हैं। Java7 सत्यापनकर्ता इसे संभालने के लिए सुसज्जित नहीं है। पुराने सभी बायोटेक का उपयोग किया जाता है, लेकिन एक नए तरीके से।
जोनाथन एस। फिशर

1
मुझे आश्चर्य है कि इतने सारे भाषा विशेषताओं के साथ कंपाइलर कैसे jdk5 के लक्ष्य jvm रिलीज को प्राप्त कर सकते हैं।
मैरिनो एक

1
@MarinosAn क्या आप वास्तव में मतलब है? लक्षण है कि ठोस तरीकों, जैसे होते हैं साथ एमआई class C extends A with B, सामान्य इंटरफेस के साथ लागू किया गया है Aऔर Bऔर साथी वर्गों A$classऔर B$class। क्लास Cकेवल आगे की ओर स्टैटिक साथी क्लासेस की विधियाँ। स्व-प्रकार बिल्कुल लागू नहीं होते हैं, लैम्बदास को सार-समय पर अमूर्त आंतरिक कक्षाओं में स्थानांतरित किया जाता है, इसलिए यह एक new D with A with Bअभिव्यक्ति है। पैटर्न-मिलान अगर-और संरचनाओं का एक गुच्छा है। गैर-स्थानीय रिटर्न? लैम्ब्डा से तंत्र को पकड़ने की कोशिश। कुछ भी बचा है? (दिलचस्प है, मेरी खोपड़ी कहती है कि 1.6 डिफ़ॉल्ट है)
Adowrath

1
बेशक, स्व-प्रकार आदि को विशेष वर्ग विशेषताओं और एनोटेशन में एन्कोड किया गया है ताकि पहले से संकलित कक्षाओं का उपयोग करते समय स्केलक नियमों का उपयोग कर सकें और लागू कर सकें।
16


-5

आप कर सकते हैं -source 1.7 -target 1.7तो यह संकलन करेगा। लेकिन यह संकलित नहीं करेगा यदि आपके पास लैम्ब्डा जैसे जावा 8 विशिष्ट विशेषताएं हैं


यह प्रश्न स्पष्ट रूप से नई भाषा की विशेषताओं का उपयोग करता है, इसलिए -source 1.7यह उड़ान नहीं भरेगा।
टूलफोर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.