जावा में कास्टिंग चर


84

मुझे आश्चर्य है कि अगर कोई मुझे बताए कि कास्टिंग कैसे काम करती है? मैं समझता हूं कि मुझे कब करना चाहिए, लेकिन वास्तव में यह नहीं कि यह कैसे काम करता है। आदिम डेटा प्रकारों पर मैं आंशिक रूप से समझता हूं, लेकिन जब यह कास्टिंग ऑब्जेक्ट्स की बात आती है तो मुझे समझ नहीं आता कि यह कैसे काम करता है।

प्रकार के साथ कोई वस्तु केवल अचानक कैसे डाली जा सकती है, आइए बताते हैं, MyType(सिर्फ एक उदाहरण) और फिर सभी विधियां प्राप्त करें?



जवाबों:


182

जावा में कास्टिंग करना जादू नहीं है, यह आप कंपाइलर को बता रहे हैं कि टाइप ए का ऑब्जेक्ट वास्तव में अधिक विशिष्ट प्रकार का बी है, और इस प्रकार बी पर सभी तरीकों तक पहुंच प्राप्त करना है जो आपके पास अन्यथा नहीं होता। आप कास्टिंग करते समय किसी भी प्रकार का जादू या रूपांतरण नहीं कर रहे हैं, आप अनिवार्य रूप से संकलक को बता रहे हैं "मुझ पर विश्वास करो, मुझे पता है कि मैं क्या कर रहा हूं और मैं आपको गारंटी दे सकता हूं कि इस लाइन पर यह वस्तु वास्तव में एक <डाली डालें" यहाँ टाइप करें> उदाहरण के लिए:

Object o = "str";
String str = (String)o;

ऊपर ठीक है, जादू नहीं और सभी अच्छी तरह से। ओ में संग्रहित वस्तु वास्तव में एक स्ट्रिंग है, और इसलिए हम बिना किसी समस्या के एक स्ट्रिंग में डाल सकते हैं।

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

String o = "str";
Integer str = (Integer)o; //Compilation fails here

दूसरे, यदि वे एक ही पदानुक्रम में हैं, लेकिन फिर भी एक अमान्य कलाकार है तो ClassCastExceptionरनटाइम पर फेंक दिया जाएगा:

Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here

यह अनिवार्य रूप से इसका मतलब है कि आपने संकलक के विश्वास का उल्लंघन किया है। आपने बताया है कि आप गारंटी दे सकते हैं कि वस्तु एक विशेष प्रकार की है, और यह नहीं है।

आपको कास्टिंग की आवश्यकता क्यों है? ठीक है, आपके साथ शुरू करने के लिए केवल इसकी आवश्यकता होती है जब अधिक सामान्य प्रकार से अधिक विशिष्ट प्रकार तक जा रहा हो। उदाहरण के लिए, Integerइनहेरिट करता है Number, इसलिए यदि आप एक के Integerरूप में स्टोर करना चाहते हैं Numberतो यह ठीक है (चूंकि सभी इंटेगर नंबर हैं।) हालांकि, यदि आप दूसरे रास्ते पर जाना चाहते हैं तो आपको एक कास्ट की जरूरत है - सभी नंबर इंटीजर नहीं हैं (साथ ही पूर्णांक के रूप में हमारे पास Double, Float, Byte, Long, आदि) वहाँ और अगर अपनी परियोजना या JDK में सिर्फ एक उपवर्ग, किसी को आसानी से एक बना सकते हैं और है कि वितरित कर सकता है, तो आप कोई गारंटी नहीं है यहां तक कि अगर आपको लगता है यह एक एकल, स्वाभाविक पसंद है !

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


आपके विवरण के लिए धन्यवाद। अगर मुझे यह सही समझ में आता है, तो शायद मैं नहीं करता, जब आप एक ऑब्जेक्ट डालते हैं, तो आप केवल संकलक को बता रहे हैं कि मुझे इस मेमोरीड्रेस पर ऑब्जेक्ट पता है कि इन तरीकों आदि का जवाब कैसे देना है, इसलिए मुझे इनकार न करें? क्या वो सही है?
user626912

1
@ user626912 की तरह - स्मृति पतों के संदर्भ में इसके बारे में मत सोचो। आप केवल संकलक को यह नहीं बता रहे हैं कि दी गई वस्तु एक अंतरफलक के अनुरूप है और इसलिए दिए गए तरीकों का कार्यान्वयन है (आप समान विधियों के साथ एक पूरी तरह से अलग वस्तु बना सकते हैं और जरूरी काम नहीं करेंगे।) आप संकलक को बता रहे हैं। एक प्रकार की वस्तु वास्तव में एक अधिक विशिष्ट प्रकार है, और इसलिए आप उस अधिक विशिष्ट वस्तु पर उपलब्ध विधियों का उपयोग कर सकते हैं। बहुरूपता पर एक लेख पढ़ें यदि आप पहले से ही नहीं है, तो यह कुछ चीजों को स्पष्ट करने में मदद कर सकता है।
माइकल बेरी

मुझे आपके बयान पर संदेह है "आपको केवल इसकी आवश्यकता है जब अधिक सामान्य प्रकार से अधिक विशिष्ट प्रकार तक जा रहा हो"। ।
फल

1
@ @ Promote आप केवल इस मामले में एक आदिम को बढ़ावा देने के लिए कास्टिंग का उपयोग कर रहे हैं - यह अधिक सामान्य प्रकार में जाने के समान नहीं है, और चीजों को करने का एक बहुत ही अजीब तरीका है। अधिक सामान्य (बेहतर) तरीका होगा Double.valueOf(gpsLastLoc.getLatitude()).getClass().getSimpleName()। या तो मामले में, आपको कभी भी एक आदिम की कक्षा को गतिशील रूप से प्राप्त करने की आवश्यकता नहीं होनी चाहिए, क्योंकि यदि getLatitude()कोई दोहरा आदिम लौटाता है, तो आप हमेशा जानते हैं कि यह किसी Doubleवस्तु को बढ़ावा देने वाला है।
माइकल बेरी

मुझे आपके द्वारा लगाए गए तरीके से प्यार है, कि कोड ने "संकलक के विश्वास का उल्लंघन किया है"। (Ps। आपके पास एक टाइपो है, आपने "यू" के बजाय "यू आर" लिखा है।)
जेसन एल।

7

वास्तव में, कास्टिंग हमेशा काम नहीं करता है। यदि ऑब्जेक्ट कोई ऐसा instanceofवर्ग नहीं है जिसे आप इसे कास्टिंग कर रहे हैं तो आपको एक ClassCastExceptionरनटाइम मिलेगा ।


5

मान लीजिए आप एक कास्ट करने के लिए करना चाहता था Stringएक करने के लिए File(कोई मतलब हाँ यह नहीं है), तो आप सीधे क्योंकि डाली नहीं कर सकता Fileवर्ग एक बच्चे और का जनक नहीं नहीं है Stringवर्ग (और संकलक शिकायत)।

लेकिन आप अपने डाली सकता है Stringकरने के लिए Objectहै, क्योंकि एकString एक Object( Objectमाता-पिता है)। तब आप इस ऑब्जेक्ट को एक में डाल सकते हैं File, क्योंकि एक फ़ाइल एक है Object

इसलिए आप सभी कार्यों का संकलन समय पर टाइपिंग की दृष्टि से 'कानूनी' है, लेकिन इसका मतलब यह नहीं है कि यह रनटाइम पर काम करेगा!

File f = (File)(Object) "Stupid cast";

कंपाइलर इसे अनुमति देगा भले ही इसका कोई मतलब न हो, लेकिन यह इस अपवाद के साथ रनटाइम पर दुर्घटनाग्रस्त हो जाएगा:

Exception in thread "main" java.lang.ClassCastException:
    java.lang.String cannot be cast to java.io.File

3

एक संदर्भ कास्टिंग केवल तभी काम करेगा जब यह एक instanceofप्रकार है। आप यादृच्छिक संदर्भ नहीं दे सकते। साथ ही, आपको और अधिक पढ़ने की आवश्यकता है Casting Objects

जैसे

String string = "String";

Object object = string; // Perfectly fine since String is an Object

String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.

3

सही तरीका यह है:

Integer i = Integer.class.cast(obj);

विधि cast()संकलन-समय कास्टिंग के लिए एक अधिक सुरक्षित विकल्प है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.