2013-07-11 6 views
5

मान लीजिए वहाँ निम्नलिखित कोड है:प्रतिबिंब कास्टिंग अपवाद फेंकते समय निहित कास्टिंग कार्य क्यों करता है?

@SuppressWarnings("unchecked") 
public static <T> T implicitCaster(Class<T> cls, Object o) { 
    return (T) o; 
} 

public static <T> T reflectionCaster(Class<T> cls, Object o) { 
    return cls.cast(o); 
} 

निम्न अपवादों के साथ दोनों ही मामलों में की उम्मीद, पुरातन में पाए गए कोड काम करता है:

public static void main(String[] args) { 
    System.out.println(implicitCaster(int.class, 42)); 
    System.out.println(reflectionCaster(int.class, 42)); 
} 

पहली कॉल काम करता है के रूप में उम्मीद लेकिन दूसरी कॉल java.lang.ClassCastException फेंकता है।

क्या यह एक कोने का मामला है जिसमें ऑटोबॉक्सिंग को नजरअंदाज कर दिया गया था? या प्रतिबिंब कास्टिंग के इस मामले में ऑटोबॉक्सिंग प्रदान करना असंभव है? या इस विसंगति के कारण कुछ और है?

संपादित करें: इस कोड को बुला काम करता है के रूप में उम्मीद:

public static void main(String[] args) { 
    System.out.println(implicitCaster(Integer.class, 42)); 
    System.out.println(reflectionCaster(Integer.class, 42)); 
} 

उत्तर

3

इस प्रकार का विलोपन की वजह से होता है।

रनटाइम पर, जेनेरिक प्रकार पैरामीटर मौजूद नहीं हैं।
किसी ऑब्जेक्ट को सामान्य प्रकार पैरामीटर पर कास्ट करने से कोई प्रभाव नहीं पड़ता है। (यही कारण है कि आपको अनचेक कास्ट चेतावनी मिलती है)

इसलिए, आपकी पहली पंक्ति autoboxes 42 से Object विधि को पास करने के लिए।
फ़ंक्शन तब Object लौटाता है, जो System.out.println पर भेजा जाता है।


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

त्रुटि तब होती है जब cast()checks isInstance() यह सत्यापित करने के लिए कि कास्ट मान्य है।

isInstance() say के लिये दस्तावेज:

विशेष रूप से, अगर यह क्लास वस्तु एक घोषित वर्ग का प्रतिनिधित्व करता है, इस विधि TRUE देता निर्दिष्ट वस्तु तर्क का प्रतिनिधित्व किया वर्ग का एक उदाहरण है (या इसके उपवर्गों में से किसी का) ; यह अन्यथा झूठी वापसी करता है। यदि यह क्लास ऑब्जेक्ट एक सरणी वर्ग का प्रतिनिधित्व करता है, तो यह विधि सत्य लौटाती है यदि निर्दिष्ट ऑब्जेक्ट तर्क को पहचान रूपांतरण द्वारा सरणी वर्ग के किसी ऑब्जेक्ट में परिवर्तित किया जा सकता है या विस्तृत संदर्भ रूपांतरण द्वारा; यह अन्यथा झूठी वापसी करता है। यदि यह क्लास ऑब्जेक्ट एक इंटरफ़ेस का प्रतिनिधित्व करता है, तो यह विधि सत्य लौटाती है यदि निर्दिष्ट ऑब्जेक्ट तर्क का वर्ग या कोई सुपरक्लास इस इंटरफ़ेस को लागू करता है; यह अन्यथा झूठी वापसी करता है। यदि यह कक्षा वस्तु एक आदिम प्रकार का प्रतिनिधित्व करती है, तो यह विधि झूठी होती है।

(जोर जोड़ा)


आपका संपादन काम करता है क्योंकि अब आप एक आदिम प्रकार का उपयोग कर रहे हैं।
दोनों मामलों में, कंपाइलर autoboxes 42 ताकि इसे किसी ऑब्जेक्ट के रूप में पारित किया जा सके।

पहले कॉल, जैसा कि पहले है, का कोई प्रभाव नहीं पड़ता है।
दूसरा कॉल सत्यापित करता है कि बॉक्स किए गए पूर्णांक वास्तव में Integer वर्ग का एक उदाहरण है, फिर इसे वापस कर देता है।

+0

मैंने वहां लिखा है कि कोड प्रत्येक दिए गए वर्ग के लिए प्राइमेटिव के अपवाद के साथ काम करता है; तो एक सामान्य प्रकार के लिए एक वस्तु कास्टिंग संभव है। दूसरी बात आप वस्तुओं को primitives में डाल सकते हैं। – m3th0dman

+0

@ m3th0dman: मैंने यह नहीं कहा कि यह असंभव है। मैंने कहा कि इसका रनटाइम पर कोई प्रभाव नहीं पड़ता है। – SLaks

+0

अब मैं समझता हूं; लेकिन इस तरह का कास्ट विधि का अनुबंध तोड़ नहीं है? तकनीकी रूप से कास्ट संभव है। – m3th0dman

संबंधित मुद्दे