2016-03-27 16 views
23

मैं मामले में एक double से fractional हिस्सा हटाने की कोशिश कर रहा था इसे का उपयोग पूरे है:जावा त्रिगुट ऑपरेटर अजीब व्यवहार

public static void main(String[] args) { 
    Double d = 5D; 
    System.out.println((d % 1) == 0);        // true 
    System.out.println((d % 1) == 0 ? d.intValue() : "not whole"); // 5 
    System.out.println((d % 1) == 0 ? d.intValue() : d);   // 5.0 
} 
:

(d % 1) == 0 ? d.intValue() : d 

और निम्न व्यवहार जो मुझे समझ नहीं आता का सामना करना पड़ा

जैसा कि आप तीसरी पंक्ति पर देख सकते हैं, ऑपरेटर else मान - 5.0 चुनता है भले ही (d % 1) == 0 स्थिति पूरी हो।

यहां क्या हो रहा है?

+3

यह चुनता है 'd.intValue()' दोनों ही मामलों में, यह सिर्फ रूपांतरण यकीन है कि दूसरे और तीसरे तर्क एक ही प्रकार है बनाने के लिए करता है। – Keppil

+0

शायद http://stackoverflow.com/questions/8002603/why-does-the-ternary-operator-unexpectedly-cast-integers (और इसके सभी डुप्लिकेट) के डुप्लिकेट के रूप में माना जा सकता है ... – Marco13

+0

@ मार्को 13, मैं था इस बात को ध्यान में रखते हुए कि सवाल पोस्ट करते समय कास्टिंग समस्या थी। हो सकता है कि यह हिंडसाइट द्वारा डुप्लिकेट हो .. – Daniel

उत्तर

35

त्रिगुट सशर्त ऑपरेटर की वापसी प्रकार ऐसा है कि दोनों 2 और 3 ऑपरेंड इसे करने के लिए सौंपा जा सकता है किया जाना चाहिए।

Object इसलिए, अपने दूसरे मामले में, ऑपरेटर की वापसी प्रकार है (दोनों d.intValue() और "not whole" के बाद से यह करने के लिए आबंटित होना चाहिए) जबकि तीसरे मामले में यह Double है (दोनों d.intValue() और d के बाद से यह करने के लिए आबंटित किया जाना चाहिए)।

मुद्रण एक Object जिसका क्रम प्रकार, जबकि मुद्रण एक Double आप 5.0 देता Integer आप 5 देता है।

+0

लेकिन इसे 'ऑब्जेक्ट' पर क्यों डाला जा रहा है और 'स्ट्रिंग' नहीं है जब दोनों को 'स्ट्रिंग' को असाइन किया जा सकता है? – Daniel

+3

@ डैनियल वास्तव में, 'इंटीगर' को 'स्ट्रिंग' को असाइन नहीं किया जा सकता है, इसे पहले स्ट्रिंग में परिवर्तित करना होगा (उदाहरण के लिए, 'इंटेगर' के 'toString' का उपयोग करके)। Println द्वारा मुद्रित होने के लिए यह केवल आपके उदाहरण में एक स्ट्रिंग में परिवर्तित हो गया है। – Eran

3

यह सही ढंग से चुनता है। फिर यह इसे डबल में लपेटता है। ये 3 मुख्य बिंदु हैं:

  1. यदि दूसरे और तीसरे ऑपरेटरों का एक ही प्रकार है, तो यह सशर्त अभिव्यक्ति का प्रकार है। दूसरे शब्दों में, आप मिश्रित प्रकार की गणना के स्पष्ट स्टीयरिंग द्वारा पूरी गड़बड़ी से बच सकते हैं।

  2. यदि ऑपरेटरों में से एक प्रकार टी है, जहां टी टी बाइट, शॉर्ट, या चार है और अन्य ऑपरेंड टाइप इंटेल की निरंतर अभिव्यक्ति है जिसका मूल्य टाइप टी में प्रतिनिधित्व योग्य है, तो सशर्त अभिव्यक्ति का प्रकार टी है

  3. अन्यथा, बाइनरी न्यूमेरिक पदोन्नति ऑपरेंड प्रकारों पर लागू होती है, और सशर्त अभिव्यक्ति का प्रकार दूसरे और तीसरे ऑपरेटरों का प्रचारित प्रकार होता है।

11

अभिव्यक्ति का प्रकार a ? b : c हमेशा c या b और c के सबसे नज़दीकी सामान्य माता-पिता के समान होता है।

System.out.println((d % 1) == 0 ? d.intValue() : "not whole"); // Comparable a parent of Integer and String 
System.out.println((d % 1) == 0 ? d.intValue() : d);   // Double is a widened int 

BTW d % 1 केवल यह है कि यह काफी छोटा एक int मूल्य में फिट करने के लिए है एक पूरी नहीं, ऐसा नहीं है कि है की जाँच करेगा। का अधिक सुरक्षित की जांच करता है, तो मूल्य एक ही है जब एक int या long

लिए डाली या आप इसे

double d = 5.0; 
System.out.println((long) d == d ? Long.toString((long) d) : Double.toString(d)); 
+1

धन्यवाद, मेरे मामले में (संख्या सीएसएटी का प्रतिनिधित्व करती है) अधिकतम संभव मूल्य 5 है इसलिए जीवन की तुलना में जीवन का आभारी सरल है .. – Daniel

1

आपके मामले में के साथ एक डबल करने के लिए वापस long चौड़ा करने को रोका जा सकता है देखने के लिए है टर्नरी ऑपरेटर के दूसरे और तीसरे तर्क प्रकार "int" और "डबल" हैं। जावा को इन मानों को एक ही प्रकार में परिवर्तित करना होगा ताकि उन्हें टर्नरी ऑपरेटर से वापस किया जा सके।ऐसा करने के लिए नियम जावा भाषा विनिर्देश में दिए गए हैं। https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25

आपके मामले में इन नियमों के परिणामस्वरूप "डबल" टाइप करने के लिए दोनों पैरामीटर का रूपांतरण होता है ("डबल" अनबॉक्स किया जाता है, int मूल्य-रूपांतरित होता है)।

फिक्स टर्नरी ऑपरेटर को तर्क डालना है ताकि वे एक ही प्रकार के हों (सख्ती से आवश्यकतानुसार नीचे में अधिक ब्रैकेट हो सकते हैं, मैं जावा ऑपरेटर प्राथमिकता नियमों पर थोड़ा सा जंगली हूं)।

System.out.println((d % 1) == 0 ? ((Number)(d.intValue())) : (Number)d); 
संबंधित मुद्दे