java - क्यों एक जावा 8 में एक इंटेगर रैपर पर स्विच, एक 'चार' मामले को संकलित नहीं करता है, लेकिन जब बाइट खत्म हो जाता है तो संकलन ठीक है?



java-8 switch-statement (1)

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

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

संकलन ठीक है:

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

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

सबसे पहले, JLS 14.11 switch स्टेटमेंट के बारे में कहता है:

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

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

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

  • आपको लगता है कि 'a' बाद से 'a' एंगर के लिए असाइन किया जाना चाहिए क्योंकि 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 बॉक्स को चौड़ा करने की आवश्यकता होगी। लेकिन यदि आप उन रूपांतरणों के संयोजनों को देखते हैं, जिनकी अनुमति है, तो आप बॉक्सिंग रूपांतरण के बाद एक व्यापक आदिम रूपांतरण नहीं कर सकते।

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

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

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

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

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

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

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

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

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






switch-statement