2015-10-22 5 views
7

मेरे कोड:मुझे जेनेरिक टाइप टी में क्यों डालना चाहिए, भले ही मुझे पता चले कि यह सही ढंग से लौटाता है?

private static <T> T get(Class<T> clazz) throws IllegalAccessException, InstantiationException { 
     if (clazz.equals(String.class)) { 
      return (T) new String("abc");//line x 
     } else { 
      return clazz.newInstance(); 
     } 

    } 

जैसा कि आप देख, line x में, TString.class रहना होगा और String देता है। लेकिन T पर परिणाम कास्टिंग किए बिना संकलित विफल रहा।

line xreturn new String("abc"); परिणाम Incompatible types बदलें।

+1

यह वास्तव में नहीं है कि टेम्पलेट्स का क्या अर्थ है। बेशक, यह आपके लिए स्पष्ट है कि यह हमेशा कुछ प्रकार के टी को वापस कर देगा - लेकिन यह संकलक के लिए स्पष्ट है? यदि टी स्ट्रिंग नहीं है, तो अभी भी कुछ मार्ग (सुलभ या नहीं) है जो गलत प्रकार देता है। – JArkinstall

उत्तर

5

कंपाइलर if कथन को ध्यान में रखता नहीं है।

तो यह सब देखता है कि आपको T (जिसमें से इसका कोई और ज्ञान नहीं है) लौटने की आवश्यकता है। यह अनुमान नहीं लगाया गया कि T यहां String होना चाहिए।

आप चेतावनी है कि आप

return clazz.cast("abc"); 
+0

यह एक ही परिणाम उत्पन्न नहीं करता है। ओपी का कोड हर बार स्ट्रिंग का एक नया उदाहरण बनाता है, लेकिन आपका कोड हर बार एक ही (इंटर्न वाले) स्ट्रिंग देता है। हो सकता है कि 'clazz.cast (नया स्ट्रिंग ("एबीसी"));' यह भी ध्यान दिया जाना चाहिए कि कास्टिंग() में अभी भी एक असुरक्षित कलाकार शामिल है, लेकिन इसे कास्ट विधि के अंदर दफनाया गया है। – Bohemian

+0

@ बोहेमियन: मैंने चुपचाप 'नया स्ट्रिंग()' भाग को स्वत: सुधार दिया। ज्यादातर मामलों में, आप एक नया स्ट्रिंग उदाहरण नहीं चाहते हैं। 'कास्ट' यहां असुरक्षित नहीं है, क्योंकि 'if' कथन पहले से ही संगतता के लिए चेक किया गया है (जो इस प्रश्न का मुद्दा था, मुझे लगता है कि कुछ अन्य भाषाओं में मजबूत प्रकार की अनुमान है जो इस तरह की सशर्त को ध्यान में रखता है)। – Thilo

+0

क्षमा करें - "असुरक्षित" से मेरा मतलब व्यावहारिक दृश्य से असुरक्षित नहीं था, बल्कि यह कि संकलक इसे असुरक्षित मानता है और चेतावनी उत्पन्न करता है। विशेष रूप से, 'कास्ट() 'विधि' वापसी (टी) obj;' है और '@SuppressWarnings (" अनचेक ") के साथ एनोटेट किया गया है '- कॉलिंग' कास्ट() 'केवल * आपके * कोड से चेतावनी को धक्का देता है जेडीके (जो मैं ठंडा हूं - मैं इस पैटर्न का उपयोग अक्सर अपने आप में करता हूं)। – Bohemian

1

कर कारण यह है कि आप हर वर्ग के लिए स्ट्रिंग डाली नहीं कर सकता है द्वारा "मिट प्रकार के आगे वाले चेक डाली" के लिए मिल बच सकते हैं। इस बारे में सोचें कि टी एक संख्या वर्ग है, जो आप क्लासकास्ट अपवाद को फेंक देंगे।

आप समस्या को हल करने के लिए इस कोशिश कर सकते हैं:

return (T) ((Object) new String("abc")); 
0

आप इस प्रकार के रूप में कास्ट से बच सकते हैं:

if (clazz.equals(String.class)) { 
    return clazz.getDeclaredConstructor(String.class).newInstance("abc"); 
} 
return clazz.newInstance(); 

आप कुछ अपवादों को पकड़ने के लिए (और ध्यान न दें) होगा।

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