क्यों एक पूर्णांक आवरण पर जावा स्विच में, एक 'चार' मामला संकलित नहीं करता है, लेकिन संकलित ठीक है जब स्विच बाइट पर है?


18

संकलन नहीं है:

void test(Integer x) {
      switch (x) {
          case 'a':
      }
}

संकलन ठीक है:

void test(Byte x) {
      switch(x) {
          case 'a':
      }
}

1
पूर्णांक 4 बाइट्स है जबकि चार बाइट्स है। इसलिए पहले मामले में, कोई फर्क नहीं पड़ता कि आप किस चरित्र को लिखते हैं, यह पूर्णांक से छोटा है। हालाँकि, दूसरे मामले में, आपके द्वारा लिखा गया चरित्र अधिकतम बाइट से बड़ा हो सकता है, जिससे यह मामला कभी भी निष्पादित नहीं होता है।
जारोस्लाव पावलक

वह स्पष्टीकरण गलत है। दरअसल, दूसरे उदाहरण में, 'a'मामले में कोड को उस मामले में निष्पादित किया जाएगाx जो बाइट है 97। (यदि आप मुझ पर विश्वास नहीं करते हैं तो यह कोशिश करें।) वास्तविक स्पष्टीकरण के लिए, मेरा उत्तर देखें।
स्टीफन सी

जवाबों:


19

कारण बल्कि जटिल हैं, लेकिन वे जावा लैंग्वेज स्पेसिफिकेशन के विवरण में हैं ( यदि आप चाहें तो ठीक प्रिंट करें )।

सबसे पहले, जेएलएस 14.11 में कहा गया है कि switchबयानों के बारे में निम्नलिखित हैं :

"स्विच स्टेटमेंट से जुड़े प्रत्येक मामले को स्विच स्टेटमेंट के एक्सप्रेशन ( " 5.2 ) के प्रकार के साथ संगत असाइनमेंट होना चाहिए ।"

इसका मतलब है कि क्रमशः और 'a'करने के लिए असाइन करने की आवश्यकता है ।IntegerByte

लेकिन यह सही नहीं लगता है:

  • आपको लगता है कि होगा कि चूंकि 'a' होना चाहिए एक के लिए आबंटित Integerक्योंकि char-> int काम कानूनी है। (किसी भी charमूल्य में फिट होगा int)

  • आपको लगता है कि होगा कि जब 'a' नहीं होना चाहिए एक के लिए आबंटित Byteक्योंकि char-> byte काम नहीं कानूनी है। (अधिकांश charमूल्य एक बाइट में फिट नहीं होंगे।)

वास्तव में, इनमें से कोई भी सही नहीं है। यह समझने के लिए कि, हमें यह समझने की आवश्यकता है कि असाइनमेंट संदर्भों में जेएलएस 5.2 वास्तव में क्या अनुमति है।

"असाइनमेंट संदर्भों में से एक निम्नलिखित के उपयोग की अनुमति देता है :

  • एक पहचान रूपांतरण (.15.1.1)
  • एक व्यापक आदिम रूपांतरण (.15.1.2)
  • एक व्यापक संदर्भ रूपांतरण (.15.1.5)
  • एक अनबॉक्सिंग रूपांतरण के बाद एक व्यापक संदर्भ रूपांतरण
  • एक व्यापक संदर्भ रूपांतरण के बाद एक अनबॉक्सिंग रूपांतरण, उसके बाद एक व्यापक आदिम रूपांतरण
  • एक बॉक्सिंग रूपांतरण (.15.1.7)
  • एक बॉक्सिंग रूपांतरण के बाद एक व्यापक संदर्भ रूपांतरण होता है
  • एक अनबॉक्सिंग रूपांतरण (.15.1.8)
  • एक व्यापक रूपांतरण के बाद एक अनबॉक्सिंग रूपांतरण। "

से जाने के लिए 'a'करने के लिए Integer, हम करने की आवश्यकता होगी 1 को चौड़ा charएक के लिए मूल्य intतो बॉक्स intएक करने के लिए Integer। लेकिन यदि आप उन रूपांतरणों के संयोजनों को देखते हैं जो अनुमत हैं, तो आप बॉक्सिंग रूपांतरण के बाद एक व्यापक आदिम रूपांतरण नहीं कर सकते।

इसलिए 'a'करने के लिए Integerअनुमति नहीं है। यह पहले मामले में संकलन त्रुटि बताता है।

आपको लगता है कि होता है कि 'a'करने के लिए Byteकी अनुमति नहीं है, क्योंकि वह एक आदिम संकुचन रूपांतरण ... जो सब पर सूची में नहीं है शामिल होगा। वास्तव में, शाब्दिक एक विशेष मामला है। जेएलएस 5.2 निम्नलिखित कहती है।

"इसके अलावा, यदि अभिव्यक्ति प्रकार बाइट, लघु, चार या उदाहरण के एक स्थिर अभिव्यक्ति ( 815.28 ) है:

  • एक संकरा आदिम रूपांतरण का उपयोग किया जा सकता है यदि चर प्रकार बाइट, लघु, या चार है, और स्थिर अभिव्यक्ति का मूल्य चर के प्रकार में प्रतिनिधित्व करने योग्य है।

  • यदि वैरिएबल प्रकार का है एक संकुचन आदिम रूपांतरण एक बॉक्सिंग रूपांतरण के बाद इस्तेमाल किया जा सकता Byte, Shortया Character, और निरंतर अभिव्यक्ति के मूल्य प्रकार बाइट में प्रदर्शनीय, कम है, या क्रमशः चार। "

इनमें से दूसरा इस पर लागू होता 'a'है Byte, क्योंकि:

  • एक चरित्र शाब्दिक एक निरंतर अभिव्यक्ति है, और
  • का मान 'a'है 97, जिसके लिए सीमा में है, दशमलव byte( -128करने के लिए +127)।

यह बताता है कि दूसरे उदाहरण में कोई संकलन त्रुटि क्यों है।


1 - हम बॉक्स नहीं कर सकते हैं 'a'एक करने के लिए Characterऔर फिर चौड़ा Characterकरने के लिए Integerक्योंकि Characterकी एक जावा उप प्रकार नहीं है Integer। यदि स्रोत प्रकार लक्ष्य प्रकार का एक उपप्रकार है, तो आप केवल एक विस्तृत संदर्भ रूपांतरण का उपयोग कर सकते हैं।


क्या हम intस्विच प्रकार के रूप में उपयोग कर सकते हैं ? (चूँकि char -> intआदिम चौड़ीकरण की अनुमति है)
अज़हरचर्ल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.