सवाल जावा का + =, - =, * =, / = यौगिक असाइनमेंट ऑपरेटरों को कास्टिंग की आवश्यकता क्यों नहीं है?


आज तक, मैंने सोचा कि उदाहरण के लिए:

i += j;

सिर्फ एक शॉर्टकट है:

i = i + j;

लेकिन अगर हम इसे आजमाएं तो क्या होगा:

int i = 5;
long j = 8;

फिर i = i + j; संकलित नहीं करेंगे लेकिन i += j; ठीक संकलित करेंगे।

इसका मतलब यह है कि वास्तव में i += j; इस तरह कुछ के लिए एक शॉर्टकट है i = (type of i) (i + j)?


3286
2018-01-03 10:10


मूल


मुझे आश्चर्य है कि जावा अपने पूर्ववर्तियों की तुलना में एक कठोर भाषा होने की अनुमति देता है। कास्टिंग में त्रुटियों में गंभीर विफलता हो सकती है, जैसा एरियन 5 फ्लाइट 501 के मामले में था, जहां 16-बिट पूर्णांक में 64-बिट फ्लोट कास्ट क्रैश हुआ। - SQLDiver
जावा में लिखी गई एक फ्लाइट कंट्रोल सिस्टम में, यह आपकी चिंताओं @SQLDiver की कम से कम होगी - Ross Drew
के संभावित डुप्लिकेट जावा में + = 10 और ए = ए +10 के बीच अंतर? - phuclv
वास्तव में i+=(long)j; ठीक भी संकलित करेंगे। - Tharindu
मुझे लगता है कि डगलस क्रॉकफोर्ड सभी के बाद तर्क जीतता है ... यह व्यवहार भयानक है और कई भाषाओं में रूपांतरणों के आसपास समान समस्याएं हैं। - Aluan Haddad


जवाब:


हमेशा इन सवालों के साथ, जेएलएस का जवाब है। इस मामले में §15.26.2 कंपाउंड असाइनमेंट ऑपरेटर। निष्कर्ष:

फॉर्म की एक यौगिक असाइनमेंट अभिव्यक्ति E1 op= E2 के बराबर है E1 = (T)((E1) op (E2)), कहा पे T का प्रकार है E1, सिवाय इसके कि E1 केवल एक बार मूल्यांकन किया जाता है।

एक उदाहरण से उद्धृत §15.26.2

[...] निम्नलिखित कोड सही है:

short x = 3;
x += 4.6;

और x में मान 7 होने का परिणाम है क्योंकि यह इसके बराबर है:

short x = 3;
x = (short)(x + 4.6);

दूसरे शब्दों में, आपकी धारणा सही है।


2212
2018-01-03 10:15



इसलिए i+=j संकलित करता है क्योंकि मैंने खुद को चेक किया है, लेकिन इसके परिणामस्वरूप परिशुद्धता का नुकसान होगा? यदि ऐसा है, तो यह i = i + j में ऐसा क्यों नहीं होने देता है? हमें वहां क्यों बग है? - bad_keypoints
@ronnieaka: मुझे लगता है कि भाषा डिजाइनरों को लगा कि एक मामले में (i += j), यह मानना ​​सुरक्षित है कि अन्य मामले के विपरीत परिशुद्धता का नुकसान वांछित है (i = i + j) - Lukas Eder
नहीं, यह ठीक है, मेरे सामने! क्षमा करें मैंने इसे पहले नहीं देखा था। आपके जवाब में, E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), तो यह प्रकार की तरह टाइपकास्टिंग (लंबी से int तक नीचे) की तरह है। जबकि i = i + j में, हमें इसे स्पष्ट रूप से करना है, यानी, प्रदान करें (T) में हिस्सा E1 = ((E1) op (E2)) यही है ना - bad_keypoints
मुझे लगता है कि इसका उपयोग एक स्पष्ट कलाकार और / या से बचने के लिए किया जाता है f एक छोटे से शाब्दिक को जोड़ने के लिए स्थिति में पोस्टफिक्स? - Andrey Akhmetov
जावा कंपाइलर एक टाइपकास्ट जोड़ने का एक संभावित कारण यह है कि यदि आप असंगत प्रकारों पर अंकगणित करने का प्रयास कर रहे हैं, तो अनुबंधित फ़ॉर्म का उपयोग करके परिणाम का टाइपकास्ट करने का कोई तरीका नहीं है। परिणाम का एक टाइपकास्ट आमतौर पर समस्याग्रस्त तर्क के टाइपकास्ट से अधिक सटीक होता है। असंगत प्रकारों का उपयोग करते समय कोई टाइपकास्ट संकुचन बेकार नहीं करेगा, क्योंकि यह हमेशा संकलक को त्रुटि को फेंकने का कारण बनता है। - ThePyroEagle


इस कास्टिंग का एक अच्छा उदाहरण * = या / = का उपयोग कर रहा है

byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57

या

byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40

या

char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'

या

char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'

442
2018-01-03 10:20



@ सजल दत्ता मुझे वह संदर्भ नहीं मिला। मन समझा रहा है? - Akshat Agarwal
@ अक्षतगरवाल च एक चार है। 65 * 1.5 = 97.5 -> समझ गया? - Sajal Dutta
हाँ, लेकिन मैं यहां कुछ शुरुआती आ रहा हूं, इसे पढ़ रहा हूं, और सोच रहा हूं कि आप किसी भी चरित्र को ऊपरी मामले से कम मामले में 1.5 से गुणा करके परिवर्तित कर सकते हैं। - Dawood ibn Kareem
@ डेविडवालेस किसी भी चरित्र के रूप में जब तक यह है A ;) - Peter Lawrey
@ पीटर लेवर और @ डेविड वालस मैं आपका खुलासा करूंगा गुप्त- ch += 32= D - Minhas Kamal


बहुत अच्छा सवाल है। जावा भाषा विनिर्देश आपके सुझाव की पुष्टि करता है।

उदाहरण के लिए, निम्नलिखित कोड सही है:

short x = 3;
x += 4.6;

और x में मान 7 होने का परिणाम है क्योंकि यह इसके बराबर है:

short x = 3;
x = (short)(x + 4.6);

223
2018-01-03 10:17



या अधिक मजेदार: "int x = 33333333; x + = 1.0f;"। - supercat


हाँ,

मूल रूप से जब हम लिखते हैं

i += l; 

संकलक इसे बदल देता है

i = (int)(i + l);

मैंने अभी जांच की है .class फ़ाइल कोड

वास्तव में जानना एक अच्छी बात है


163
2018-01-03 10:19



क्या आप मुझे बता सकते हैं कि यह कौन सा क्लासफाइल है? - Andrey Akhmetov
@hexafraction: कक्षा फ़ाइल द्वारा आपका क्या मतलब है? यदि आप अपनी जावा क्लास के अनुपालन संस्करण की तुलना में मेरी पोस्ट में वर्णित कक्षा फ़ाइल के बारे में पूछ रहे हैं - Umesh Awasthi
ओह, आपने "क्लास फ़ाइल कोड" का उल्लेख किया है, जिसने मुझे विश्वास दिलाया कि एक विशिष्ट क्लासफ़ाइल शामिल था। मैं समझता हूं कि अब आपका क्या मतलब है। - Andrey Akhmetov
सभी पत्रों में से, आपने वास्तव में "एल" (लोअरकेस एल) चुना है ... - Bogdan Alexandru
@glglgl मैं इस बात से असहमत हूं कि किसी को उन मामलों में अंतर करने के लिए फ़ॉन्ट पर भरोसा करना चाहिए ... लेकिन सभी को यह चुनने की आजादी है कि क्या सबसे अच्छा लगता है। - Bogdan Alexandru


आपको से कास्ट करने की जरूरत है long सेवा मेरे int  explicitly के मामले में i = i + l  तो यह संकलित और सही आउटपुट दे देंगे। पसंद

i = i + (int)l;

या

i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.

लेकिन मामले में += यह ठीक काम करता है क्योंकि ऑपरेटर सही प्रकार के प्रकार से दाएं चर के प्रकार से प्रकार कास्टिंग करता है, इसलिए स्पष्ट रूप से डालने की आवश्यकता नहीं है।


85
2018-01-03 10:15



इस मामले में, "निहित कास्ट" हानिकारक हो सकता है। हकीकत में, जैसा कि @ लुकासएडर ने अपने जवाब में कहा है, कास्ट int किया जाता है बाद  +। संकलक (चाहिए?) एक चेतावनी फेंक देगा अगर यह वास्तव में डाला गया था long सेवा मेरे int। - Romain


यहां समस्या टाइप कास्टिंग शामिल है।

जब आप int और long जोड़ते हैं,

  1. Int ऑब्जेक्ट को लंबे समय तक डाला जाता है और दोनों जोड़े जाते हैं और आपको लंबी वस्तु मिलती है।
  2. लेकिन लंबी वस्तु को अंतर्निहित रूप से int में नहीं डाला जा सकता है। तो, आपको इसे स्पष्ट रूप से करना है।

परंतु += इस तरह से कोडित किया गया है कि यह कास्टिंग प्रकार करता है। i=(int)(i+m)


56
2018-01-03 10:20





जावा प्रकार रूपांतरण स्वचालित रूप से निष्पादित होते हैं जब असाइनमेंट ऑपरेशन के दाईं ओर अभिव्यक्ति के प्रकार को असाइनमेंट के बाईं ओर चर के प्रकार के लिए सुरक्षित रूप से प्रचारित किया जा सकता है। इस प्रकार हम सुरक्षित रूप से असाइन कर सकते हैं:

 बाइट -> लघु -> int -> लंबा -> फ्लोट -> डबल। 

वही दूसरी तरफ काम नहीं करेगा। उदाहरण के लिए हम स्वचालित रूप से लंबे समय तक एक int को परिवर्तित नहीं कर सकते हैं क्योंकि पहले को दूसरे की तुलना में अधिक संग्रहण की आवश्यकता होती है और परिणामस्वरूप जानकारी खो सकती है। इस तरह के एक रूपांतरण को मजबूर करने के लिए हमें एक स्पष्ट रूपांतरण करना होगा।
प्रकार - रूपांतरण


47
2018-01-23 05:50



अरे, लेकिन long से 2 गुना बड़ा है float। - Sarge Borsch
ए float हर संभव नहीं पकड़ सकते हैं int मूल्य, और ए double हर संभव नहीं पकड़ सकते हैं long मूल्य। - Alex MDC
"सुरक्षित रूप से रूपांतरित" से आपका क्या मतलब है? उत्तर के बाद के हिस्से से मैं यह समझ सकता हूं कि आपका मतलब स्वचालित रूपांतरण (निहित कास्ट) है जो फ्लोट -> लंबे समय के मामले में बिल्कुल सही नहीं है। फ्लोट पीआई = 3.14 एफ; लंबे बी = पीआई; परिणामस्वरूप संकलक त्रुटि होगी। - Luke
आप इंटीजर आदिम प्रकारों के साथ फ़्लोटिंग पॉइंट आदिम प्रकारों को अलग करने से बेहतर होंगे। वे एक ही बात नहीं हैं। - ThePyroEagle
जावा में सरल रूपांतरण नियम हैं जिनके लिए कई पैटर्नों में कास्टों के उपयोग की आवश्यकता होती है, जहां बिना किसी जानवर के व्यवहार व्यवहार अपेक्षाओं से मेल खाते हैं, लेकिन आमतौर पर गलत तरीके से कई पैटर्न में जानवरों की आवश्यकता नहीं होती है। उदाहरण के लिए, एक कंपाइलर स्वीकार करेगा double d=33333333+1.0f; शिकायत के बिना, भले ही परिणाम 33333332.0 का इरादा नहीं था (आकस्मिक रूप से, 33333334.0f का गणित-सही उत्तर या तो के रूप में प्रतिनिधित्व किया जाएगा float या int)। - supercat


कभी-कभी, इस तरह के एक प्रश्न से एक साक्षात्कार में पूछा जा सकता है।

उदाहरण के लिए, जब आप लिखते हैं:

int a = 2;
long b = 3;
a = a + b;

कोई स्वचालित टाइपकास्टिंग नहीं है। सी ++ में उपरोक्त कोड को संकलित करने में कोई त्रुटि नहीं होगी, लेकिन जावा में आपको कुछ मिल जाएगा Incompatible type exception

तो इससे बचने के लिए, आपको अपना कोड इस तरह लिखना होगा:

int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting

37
2017-12-02 10:40



की तुलना के बारे में अंतर्दृष्टि के लिए धन्यवाद op जावा में इसके उपयोग के लिए सी ++ में उपयोग करें। मुझे हमेशा ट्रिविया के इन बिट्स को देखना पसंद है और मुझे लगता है कि वे वार्तालाप में कुछ योगदान करते हैं जिसे अक्सर छोड़ा जा सकता है। - Thomas
हालांकि सवाल खुद ही है दिलचस्प, यह पूछना साक्षात्कार में बेवकूफ है यह साबित नहीं करता है कि व्यक्ति एक अच्छी गुणवत्ता वाले कोड का उत्पादन कर सकता है - यह साबित करता है कि ओरेकल प्रमाणपत्र परीक्षा के लिए तैयार होने के लिए उसके पास पर्याप्त धैर्य था। और एक खतरनाक ऑटो-रूपांतरण का उपयोग करके असंगत प्रकारों से बचें और इस प्रकार संभावित अतिप्रवाह त्रुटि को छुपाएं, शायद यहां तक ​​कि साबित होता है कि व्यक्ति संभावित गुणवत्ता वाले कोड का उत्पादन करने में सक्षम नहीं है। इन सभी ऑटो-रूपांतरणों और ऑटो-मुक्केबाजी और सभी के लिए जावा लेखकों को डर! - Honza Zidek


मुख्य अंतर यह है कि के साथ a = a + b, कोई टाइपकास्टिंग नहीं चल रहा है, और इसलिए संकलक टाइप करने के लिए आप पर नाराज हो जाता है। लेकिन इसके साथ a += b, यह वास्तव में क्या कर रहा है टाइपकास्टिंग है b एक प्रकार के साथ संगत a। तो अगर आप करते हैं

int a=5;
long b=10;
a+=b;
System.out.println(a);

आप वास्तव में क्या कर रहे हैं:

int a=5;
long b=10;
a=a+(int)b;
System.out.println(a);

18
2018-06-07 23:27



कंपाउंड असाइनमेंट ऑपरेटर बाइनरी ऑपरेशन के नतीजे का एक संकीर्ण रूपांतरण करते हैं, न कि दाएं हाथ के ऑपरेंड। तो आपके उदाहरण में, 'ए + = बी' 'ए = ए + (इंट) बी' के बराबर नहीं है, लेकिन जैसा कि अन्य उत्तरों द्वारा समझाया गया है, 'a = (int) (a + b)'। - Lew Bloch


यहां सूक्ष्म बिंदु ...

के लिए एक अंतर्निहित टाइपकास्ट है i+j कब j एक डबल और है i एक int है जावा हमेशा जब उनके बीच एक ऑपरेशन होता है तो एक पूर्णांक को एक डबल में परिवर्तित करता है।

स्पष्टीकरण देना i+=j कहा पे i एक पूर्णांक है और j एक डबल के रूप में वर्णित किया जा सकता है

i = <int>(<double>i + j)

देख: निहित कास्टिंग का यह विवरण

आप टाइपकास्ट करना चाह सकते हैं j सेवा मेरे (int) इस मामले में स्पष्टता के लिए।


7
2018-01-18 20:07