2010-10-14 15 views
6

मैंने इस फ़ंक्शन को कार्यान्वित किया है:जावा: X से Y/अनस्टेक्ड कास्ट को CastOrNull को कार्यान्वित करने के लिए कैसे करें

 static <X,Y> Y castOrNull(X obj) { 
    try { 
    return (Y)obj; 
    } 
    catch(ClassCastException e) { 
    return null; 
    } 
} 

यह मुझे संकलक चेतावनी देता है:

Type safety: Unchecked cast from X to Y 

जिसे मैं बिल्कुल समझ नहीं पा रहा हूं। क्या try/catch नहीं है जिसे मैं यहां देख रहा हूं? क्या मैं चेतावनी को अनदेखा कर सकता हूं?

क्या मेरा कार्य अपेक्षित काम करेगा या नहीं? मैं इसे सही तरीके से कैसे कार्यान्वित करूं?

मैंने obj instanceof Y चेक के साथ भी कोशिश की लेकिन यह जावा हैंडल जेनरिक के तरीके से काम नहीं करता है।

btw।, यह फ़ंक्शन मेरे लिए काफी उपयोगी लगता है (कुछ अन्य कोड को और अधिक साफ करने के लिए)। मुझे आश्चर्य है कि जावा में ऐसा कोई फ़ंक्शन पहले से मौजूद हो सकता है?


एक उदाहरण जहां मैं इसका उपयोग करना चाहता हूं:

 void removeEmptyRawStrings() { 
     for(Iterator<Entity> e = entities.iterator(); e.hasNext();) { 
      RawString s = castOrNull(e.next()); 
      if(s != null && s.content.isEmpty()) e.remove(); 
     } 
    } 

मेरे पास अक्सर मेरे कोड में ऐसे मामले हैं। और मुझे लगता है कि यह किसी और चीज़ की तुलना में अधिक पठनीय और सरल है। लेकिन अगर आपको इस कोड को और भी सरल बनाने के बारे में कोई जानकारी है तो कृपया मुझे एक बेहतर सुझाव दें।

+0

मैं आज इस चेतावनी के बारे में सोच रहा था और क्या चेक किया गया कलाकार होना संभव था, लेकिन मुझे नहीं लगता कि आप इसे कर सकते हैं। – DeliveryNinja

उत्तर

11

तो समस्या यह है कि जेनेरिक पैरामीटर Y गतिशील कास्टिंग के लिए उपयोग किए जाने पर Object माना जाता है। यह कभी सीसीई नहीं फेंक देगा। आपको विधि पर कॉल करने के लिए सीसीई फेंक दिया गया है, क्योंकि आपने स्थिर प्रकार की सुरक्षा तोड़ दी है।

इसके अलावा X यहां पूरी तरह से व्यर्थ है:

लगभग पूर्ण रूप से सही समाधान इस तरह कुछ भी प्रयास करने के लिए नहीं है। null खराब है। कास्टिंग खराब है।

हालांकि, अगर आप बकवास लिखने के लिए निर्धारित कर रहे हैं, तो आप Class वस्तु पारित कर सकते हैं:

public static <T> T evilMethod(Class<T> clazz, Object obj) { 
    try { 
     return clazz.cast(obj); 
    } catch (ClassCastException exc) { 
     return null; 
    } 
} 
+0

आह, महान जवाब! – aioobe

+0

धन्यवाद। मैंने अपना प्रश्न यह दिखाने के लिए बढ़ाया कि मैं इसका उपयोग कहां/कैसे करना चाहता हूं। क्या आप कृपया वर्णन कर सकते हैं कि ऐसा करने के लिए यह एक बुरी बात क्यों है? और मैं इस तरह के फ़ंक्शन का उपयोग किए बिना कोड को और अधिक सरल कैसे बना सकता हूं? – Albert

+5

सीसीई को पकड़ने के बजाय 'if (clazz.isInstance (obj)' के बारे में क्या? –

1

आप इस पद्धति में चेतावनी को दबाने सकते हैं यदि आप निश्चित रूप से पता है कि यह एक समस्या @SuppressWarnings("unchecked")

4

साथ यह व्याख्या से नहीं है मैं पूरी तरह यकीन है कि यह अपेक्षा के अनुरूप काम नहीं कर रहा हूँ। (क्या आप इस पाठ्यक्रम :-) की उम्मीद पर निर्भर करता है लेकिन एक java.lang.ClassCastException (ideone में उदाहरण के परिणाम) के लिए इस कोड को इच्छा:

public class Main { 

    public static void main(String[] args) { 
     Integer o = Main.<String, Integer>castOrNull("hello"); 
    } 


    public static <X, Y> Y castOrNull(X obj) { 
     try { 
      return (Y) obj; 
     } catch (ClassCastException e) { 
      return null; 
     } 
    } 
} 

@Tom Hawtin the "correct" solution मिला है।

0

रास्ता जावा जेनरिक जहां इस कोड को अभ्यस्त बिल्कुल काम डिज़ाइन किया गया के लिए धन्यवाद। जेनेरिक केवल समय प्रकार की जांच के लिए उपयोगी होते हैं क्योंकि कक्षाएं रनटाइम पर सामान्य प्रकार की जानकारी का उपयोग नहीं करती हैं।

आपका कोड इस का संकलन किया जाएगा:

static Object castOrNull(Object obj) { 
    try { 
    return (Object)obj;//FAIL: this wont do anything 
    } 
    catch(ClassCastException e) { 
    return null; 
    } 
} 

डाली वस्तु के लिए असफल कभी नहीं होगा, और संकलित कोड संकलन समय पर उपस्थित सामान्य प्रकार के लिए पहुँच नहीं है। चूंकि कास्ट ऐसा नहीं होता है जिस तरह से आपको अनचेक ऑपरेशन के लिए चेतावनी मिलनी चाहिए।

+1

थोड़ा मिस्लीडिंग टिप्पणी आपके कोड में;) – aioobe