2013-01-21 19 views
11

मैं वर्तमान में एपी जावा में हाई स्कूल के छात्र की पढ़ाई कर रहा हूं और उसने मुझे "डबल कास्टिंग" के बारे में एक प्रश्न पूछा। मैंने पहले कभी इस शब्द को नहीं सुना था, लेकिन जाहिर है कि उसके शिक्षक को उम्मीद है कि वह उन्हें अपने आने वाले फाइनल के बारे में जान सके।"डबल कास्टिंग"

उदाहरण उसके शिक्षक प्रदान की अगर आप एक स्ट्रिंग में एक पूर्णांक कास्ट करने के लिए चाहता था, आप एक संकलक त्रुटि नहीं प्राप्त करने के लिए निम्न कार्य करने के लिए होता था:

Integer i = new Integer(5); 
String s = (String)(Object) i; 

सवाल यह है: जब आप चाहते हैं वास्तविक जीवन में ऐसा करने के लिए?

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

धन्यवाद!

+8

कि कोड निश्चित रूप से एक 'ClassCastException' तक ले जाएगा, जबकि' Integer' "Upcast" करने के लिए 'हो सकता है Object', ऑब्जेक्ट अभी भी जानता है कि यह एक 'इंटीगर' है ... दूसरा कास्टिंग असफल हो जाएगा। उसका शिक्षक क्या धूम्रपान करता है? : पी – fge

+0

@fge हाँ .. मैं किसी भी उदाहरण के बारे में नहीं सोच सकता था, जब उसने मुझसे आज पूछा, तो मैंने उसे बताया कि मैं उसे वापस ले जाऊंगा .. यह जानना अच्छा है कि यह सिर्फ एक बुरा विचार है और मैं मैं पागल नहीं हूँ। =] –

+0

कोई कारण नहीं है कि आप इस तरह के कोड क्यों लिखेंगे। यदि आप कास्ट के बाद आवश्यक अंतिम प्रकार की वस्तु को जानते हैं, तो यह है कि आप ऑब्जेक्ट को किस प्रकार डालेंगे। क्या आप निश्चित हैं कि शिक्षक का मतलब (स्ट्रिंग) ((ऑब्जेक्ट) i) नहीं है। कुछ())? – aishwarya

उत्तर

8

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

मेरा मतलब है, ऑटो toString कॉलिंग उदा। println("" + i), लेकिन फिर भी आप किसी ऑब्जेक्ट पहले करने के लिए कास्ट करने के लिए की जरूरत नहीं है ...

संपादित: टॉम के जवाब को पढ़ने के बाद मैं इस उत्तर के बारे अचानक अनिश्चित हूँ - पुरातन और (विशेष रूप से) जेनरिक वास्तव में इसका उपयोग कर सकते । मेरे पास अभी कुछ भी परीक्षण करने की क्षमता नहीं है, लेकिन इस उत्तर को पढ़ने वाले किसी भी व्यक्ति को निश्चित रूप से पर ध्यान दें (और शायद इसे ऊपर उठाएं)।

मैं लाइन के लिए छड़ी करने के लिए कोई (या कम से कम बहुत कुछ और दूर के बीच) अच्छा कारणों यह करने के लिए देखते हैं कि हालांकि, जा रहा हूँ, और प्रदान की उदाहरण निश्चित रूप से इसके साथ कोई संबंध नहीं है।

+1

शेन्ज़िगन्स को कॉल करने के लिए +1 – Mikhail

+0

@ जेफ मुझे लगता है कि यह कुछ भी अगर असुरक्षित कास्टिंग के बारे में चेतावनियां जोड़ देगा। यह क्या कर सकता है यह बिल्कुल संकलित करने की अनुमति देता है (हालांकि यह एक अच्छी बात नहीं है)। –

+0

@ TomHawtin-tackline संभवतः - मेरे पास अभी प्रयोग करने का कोई तरीका नहीं है। आप इसके बारे में सही हैं कि यह अच्छी बात नहीं है - किसी भी समय यह कोड को संकलित करने की अनुमति देता है जब यह अन्यथा ऐसा नहीं होता है कि यह एक रनटाइम अपवाद फेंक देगा (निश्चित रूप से संकलक आदि में बग को छोड़कर) – Jeff

1

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

उपर्युक्त प्रश्न में भी, वस्तुओं को बदलने के लिए अंत में एक एपीआई विधि की आवश्यकता है।

1

जैसा कि मैंने इसे सीखा है, अच्छे कोड में आपको कभी कास्टिंग करने की आवश्यकता नहीं है जब तक कि कोई अन्य विकल्प न हो, और यह स्पष्ट कास्टिंग introducing overhead है। toString() आदर्श समाधान है:

Integer i = new Integer(5); 
String s = i.toString(); 
7

जबकि "डबल कास्टिंग" निश्चित रूप से एक आम शब्द नहीं है और आप संदर्भ की कास्टिंग के किसी भी प्रकार के बहुत ही नहीं चाहिए, आप को पता है क्या होता है (एक ClassCastException) चाहिए।

  • यदि मान वास्तव में null है:

    पूर्णता के लिए, वहाँ कुछ मामलों में जहां यह नहीं सीसीई हैं।

  • प्राथमिकता शामिल सामग्री।(एर, Object [हानिपूर्ण] byte करने के लिए [सकारात्मक] char करने के लिए [unboxing] int, या int को Integer करने के लिए)
  • बदलें सामान्य प्रकार तर्क। List<String> से ObjectList<Integer> पर।
+0

Ooooooh, int-byte-char के बारे में अच्छी बात - यह वास्तव में एक उदाहरण है जो कुछ (संभावित रूप से) उपयोगी करेगा, भले ही इसे अन्य तरीकों से किया जा सके। इसके अतिरिक्त, सामान्य प्रकार के विकल्प के साथ, क्या आपको हर बार जब आप प्राप्त() 'के बिना कई प्रकार के कलाकारों के लिए एक 'सूची ' का उपयोग करने की अनुमति देते हैं? – Jeff

+0

@ जेफ कृपया नहीं! यद्यपि कुछ समान है जिसका उपयोग 'Collection.emptyXyz() 'विधियों के परिवार द्वारा किया जाता है। –

+0

ओह मेरा विश्वास करो मैं नहीं करूंगा, लेकिन मेरा जवाब वर्तमान में गलत तरीके से गलत है, और मुझे गलत स्वीकृत उत्तर पसंद नहीं है। – Jeff

0

शायद यह सवाल तर्क है? मेरा मतलब है, ऐसी विधि है जो कुछ (इंटेगर्स के साथ काम करना) की गणना करती है और ऑब्जेक्ट लौटाती है, और विधि का उपयोग जहां परिणाम स्ट्रिंग को कास्टिंग किया जाता है, आम तौर पर इस मेटोड को कुछ बार ओवरराइड किया जा सकता है, इस तरह की कार्यक्षमता जावा 1.5 से पहले उपयोग की गई थी। क्या आप जेनेरिक को परिभाषित कर रहे थे calss (लेकिन जेनेरिक्स के बिना) और प्रत्येक विधि के रिटर्न वस्तु है क्योंकि वहाँ कुछ बच्चे हैं और प्रत्येक स्वयं के प्रकार लौट सकते हैं, मैं नहीं पता है, लेकिन इस सवाल का जवाब हो सकता है, और इस

public class Main { 
    public static void main(String[] args) { 

     AbstractToDO abstractToDO2 = new SomeToDoTwo(); 
     String result2 = (String) abstractToDO2.toDo(); // here is second, all is good 

     System.out.println(result2); 

     AbstractToDO abstractToDO1 = new SomeToDoOne(); 
     String result1 = (String) abstractToDO1.toDo(); // here is second, Runtime error 

     System.out.println(result1); 

    } 

    Object onePlusOne(){ 

     return 1+1 +" "; 
    } 
} 

interface AbstractToDO{ 
    Object toDo(); 
} 

class SomeToDoOne implements AbstractToDO{ 
    @Override 
    public Object toDo() { 
     return (Object)(1+1); // here is first casting, // we can use without (Object) casting 
    } 
}class SomeToDoTwo implements AbstractToDO{ 
    @Override 
    public Object toDo() { 
     return (Object)"1+1"; // here is first casting, // we can use without (Object) casting 
    } 
} 
0

मैंने की तरह डबल कास्टिंग हाल ही में इस समस्या और इसके लिए उपयोग के लिए आते हैं। मेरे पास 2 पूर्णांक मानों और एक स्ट्रिंग वाले ऑब्जेक्ट्स की एक सरणी है। जब मैं इसे अनपैक करने के लिए आता हूं तो मुझे कुछ विभाजन करने के लिए पूर्णांक को दोहराने की आवश्यकता होती है।

समस्या यह है कि आप पूर्णांक से परिवर्तित नहीं कर सकते जब मैं यह त्रुटियों को दोगुना करने की वजह से जावा स्वचालित रूप से के रूप में Integer वस्तु आदिम नहीं int यह पता लगाता है पूर्णांक मूल्यों कास्ट करने के लिए आते हैं और दोगुना करने के लिए।

इसलिए विभाजन करने से पहले समाधान (double)(int)value का उपयोग करना है।

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

0

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

उदाहरण के लिए:

मान लीजिए कि एक Animal चलो एक Dog वर्ग के एक सुपर क्लास है। और हम जानते हैं कि Object कक्षा सभी वर्गों का सुपरक्लास है।

Dog d = new Dog(); 
Object a = d;   //no errors occur 

यहाँ, d परोक्ष एक Object वस्तु के रूप में casted है। जाहिर है, यह Object a = (Object)d;

यहां क्या होगा?

Dog d = new Dog(); 
Object a = (Animal)d; //no errors occur 

हम एक Animal वस्तु के रूप में d कास्ट कर रहे हैं, लेकिन संकलक परोक्ष एक Object वस्तु के रूप में यह कास्टिंग है। डबल कास्टिंग

कौन सा d आखिरकार डाला गया है?

स्पष्ट रूप से, यह होगा Object a = (Object)(Animal)d;

डबल कास्टिंग की वाक्य रचना को जानने का, हम पता होगा d अंत में एक Object के रूप में casted किया जाएगा, इसलिए कोई त्रुटियां होती हैं।

0

एक वास्तविक उपयोग मामला होगा:

static class Y extends X<Date> { 
//some code 
} 

List<Y> n = new ArrayList<>(); 

someMethod((List<X<Date>>)(List<?>) n); 

जहां

void someMethod(List<X<Date>>){ 
//some code 
} 
संबंधित मुद्दे