2014-10-30 6 views
5

मुझे पता चला है कि ग्रहण (ग्रहण कंपाइलर का उपयोग करके) में मैं कुछ जावा 7 भाषा विशेषताओं का उपयोग कर सकता हूं लेकिन अभी भी जावा 6 क्लास फाइलें बना सकता हूं। नीचे दी गई छवि में, आप दो जावा 7 भाषा विशेषताओं को देख सकते हैं जिन्हें जावा 6 क्लास फ़ाइल के रूप में सफलतापूर्वक संकलित किया गया है। हालांकि, अन्य जावा 7 फीचर्स, जो टिप्पणी करते हैं, संकलित नहीं करते हैं।ग्रहण मुझे जावा 6 क्लास फाइलों में कुछ जावा 7 भाषा सुविधाओं को संकलित क्यों करता है?

मेरी धारणा यह है कि ग्रहण यह निर्धारित कर रहा है कि जावा 7 भाषा विशेषताएं जावा 6 जेवीएम के साथ संगत हैं और जो नहीं हैं। उदाहरण के लिए, सामान्य प्रकार JComboBox केवल एक संकलन (और रनटाइम नहीं) सुविधा है, इसलिए मैं कल्पना कर सकता हूं कि यह कैसे संगत होगा। स्विच स्ट्रिंग सुविधा हालांकि मुझे लगता है कि होगा बाइट कोड में मतभेद बनाने के लिए और नए JVM सुविधाओं पर निर्भर हो सकता है, लेकिन मैं गलत हो सकता है ...

मेरे सवालों का:

  • ग्रहण वास्तव में बहुत चालाक पता करने के लिए है जावा 7 भाषा विशेषताएं जावा 6 क्लास फाइलों में संकलित करने में सक्षम हैं और नहीं हैं?

  • नीचे दिया गया उदाहरण स्पष्ट रूप से 1.6 स्रोत संगत नहीं है, तो "स्रोत संगतता" को 1.6 तक क्यों सेट करना त्रुटि उत्पन्न नहीं करता है?

  • यह "चाल" मुझे कम से कम कुछ जावा 7 भाषा सुविधाओं का उपयोग करने देता है और अभी भी जावा 6 क्लास फाइलें बनाते हैं। स्रोत 1.7 के साथ जावैक का उपयोग करना और लक्ष्य 1.6 विफल हो जाएगा, तो यह क्यों काम करता है? क्या Ecilpse कंपाइलर में एक सुविधा है जो javac नहीं करता है?

enter image description here

तुलना यहाँ रखने के लिए परिणाम जब मैं, एक जावा 6 संकलक करने के लिए स्विच के रूप में उम्मीद है।

enter image description here

उत्तर

0

मेरा अनुमान है कि आप के बारे में क्यों ECJ जब जावा 6. जेनेरिक्स करने के लिए सेट somethings व अन्यों को संकलित कर देगा सिर्फ एक ही बातें करने के लिए नीचे संकलन है तो यह डाले के रूप में सही हो सकता है यही कारण है कि यह करता है, तो काम करता है हो रहा है लक्ष्य जावा 6 पर सेट है?

जावैक और ईसीजे के बीच अन्य अंतरों के लिए What is the difference between javac and the Eclipse compiler? देखें।

1

मुझे लगता है कि दो बातें हो रही हैं:

  1. मुझे लगता है कि पहली पंक्ति (सामान्य JComboBox के साथ) काम करता है क्योंकि जावा 1.7 rt.jar जावा 1.6 rt.jar के बजाय जुड़ा हुआ है (मैं एक परियोजना जो सेटअप है जावाएसई-1.6 के साथ, और उस स्थिति में, पहली पंक्ति सेटिंग्स के आपके पहले संयोजन के साथ भी संकलित नहीं होती है)। लेकिन यह एक क्लास लाइब्रेरी मुद्दा है, न कि भाषा संस्करण मुद्दा। (यदि आप इसे चलाने के बजाए अपने नए ऐप को rt.jar के विरुद्ध संकलित करते हैं तो आप javac के साथ भी कई समस्याएं प्राप्त कर सकते हैं)।

  2. दूसरी पंक्ति शायद ग्रहण कंपाइलर में एक बग का प्रतिनिधित्व करती है। जबकि अधिकांश जावा 7 नई भाषा सुविधाओं को पूरी तरह से कंपाइलर में लागू किया जा सकता है (जो एंड्रॉइड 2013 के उत्तरार्ध से करता है), ऐसा करना स्पष्ट रूप से जावा 6 के साथ स्रोत-संगत नहीं है।

तो, संक्षेप में, आप कम से कम एक बग एक (शायद) असामान्य ग्रहण विन्यास में मिल गया है। ख्याल रखना और उस पर भरोसा मत करो।

0

यह जेआरई सिस्टम लाइब्रेरी के कारण हो सकता है जो आपके प्रोजेक्ट के बिल्ड पथ पर कॉन्फ़िगर किया गया है जो आपके द्वारा चुने गए अनुपालन स्तर से मेल नहीं खाता है। आम तौर पर आप लगभग हमेशा परियोजना के कंपाइलर सेटिंग्स में "निष्पादन पर्यावरण से अनुपालन का उपयोग करें" विकल्प का चयन करना चाहते हैं। अपने प्रोजेक्ट के बिल्ड पथ की जांच करें और देखें कि आपने निष्पादन पर्यावरण के रूप में जेआरई सिस्टम लाइब्रेरी निर्दिष्ट की है या नहीं।

1

मुझे नहीं पता कि ग्रहण क्यों अनुमति देता है या यह सिर्फ एक बग है। 1.7 javac आपको बताएगा कि

error: strings in switch are not supported in -source 1.6 

मैं भी क्यों JComboBox काम करता है,

System.out.println(new JComboBox<String>() {}.getClass().getGenericSuperclass()); 

> javax.swing.JComboBox<java.lang.String> 

कार्यावधि में सामान्य जानकारी है कि वहां नहीं होना चाहिए है पता नहीं है। उन वर्गों के लिए जेनेरिक का उपयोग करने की अनुमति जो सामान्य नहीं हैं, उन्हें आईएमओ को असंगत के रूप में खारिज कर दिया जाना चाहिए। हालांकि मैं JVM6 पर कोड से ऊपर नहीं चला था। शायद यह भी दुर्घटनाग्रस्त हो जाएगा।

लेकिन कम से कम switch तकनीकी रूप से कोई समस्या नहीं है। http://www.benf.org/other/cfr/java7switchonstring.html दिखाता है कि यह केवल एक कंपाइलर चाल है जिसके लिए कोई नई भाषा सुविधा, एपीआई या बाइटकोड की आवश्यकता नहीं है।

थोड़ा सरल उदाहरण:

int java7(String string) { 
    switch (string) { 
     case "BB": 
      return 12; 
     case "FRED": 
      return 13; 
    } 
    return 0; 
} 

अनिवार्य रूप से

int java6(String string) { 
    switch (string.hashCode()) { 
     case 2112: 
      if (string.equals("BB")) 
       return 12; 
      break; 
     case 2166379: 
      if (string.equals("FRED")) 
       return 13; 
      break; 
    } 
    return 0; 
} 

तथ्य यह है कि String#hashCode() के परिणाम निर्दिष्ट किया जाता है और कोई बदलाव नहीं करना चाहिए पर आधारित है कि हो जाता है। संकलक आपको अन्यथा कानूनी कोड को लिखने के लिए कुछ समय बचाता है।

उसी हीरे ऑपरेटर पर लागू होना चाहिए: उदा। new ArrayList<>() को संकलक द्वारा आसानी से हल किया जा सकता है।

एंड्रॉइड उपकरण, जो समान अर्ध 7 संगतता की अनुमति देता है, आपको इसका उपयोग करने की अनुमति देता है। हालांकि, अंतर यह है कि वे जावा 7 पर लक्षित .class फ़ाइलों का उपयोग करते हैं। एंड्रॉइड को .class फ़ाइलों को इसके आंतरिक स्वरूप में कनवर्ट करने की आवश्यकता है, इसलिए उनके .class से .dex कंपाइलर एंड्रॉइड रनटाइम द्वारा समझाए गए निर्देश जेनरेट करने के लिए जो भी इनपुट काम करता है उसका उपयोग कर सकता है।

कोशिश के साथ-संसाधन उदाहरण काम नहीं करेगा क्योंकि यह दूसरों के बीच की आवश्यकता है के लिए साथ AutoCloseable इंटरफ़ेस जावा 6.

और लैम्ब्डा भाव की तरह विशेष सुविधाओं में मौजूद नहीं था और साथ ही बाईटकोड के नए प्रकार की आवश्यकता होती है।

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