2010-04-22 17 views
24

मुझे लगता है कि मुझे अनचेक कास्ट का अर्थ मिलता है (एक अलग प्रकार के दूसरे से कास्टिंग), लेकिन कास्ट "चेक" करने का क्या अर्थ है? मैं कलाकारों की जांच कैसे कर सकता हूं ताकि मैं ग्रहण में इस चेतावनी से बच सकूं?अनचेक कास्ट क्या है और मैं इसे कैसे देखूं?

+1

स्रोत कोड पोस्ट करें। –

+12

कोड पोस्ट न करें! मछली पकड़ने के बजाए उन्हें आपको मछली न दें :) नहीं, गंभीरता से, सामान्य प्रश्न के लिए सामान्य जवाब होना चाहिए, भले ही शौकिया शैली में सवाल पूछा जाए। – Mike

उत्तर

28

अनचेक कास्ट का मतलब है कि आप एक सामान्य प्रकार से एक गैर-प्रकार के प्रकार या अन्य तरीकों से कास्टिंग (स्पष्ट रूप से या स्पष्ट रूप से) कास्टिंग करते हैं। जैसे यह लाइन

Set<String> set = new HashSet(); 

ऐसी चेतावनी उत्पन्न करेगा।

आमतौर पर ऐसी चेतावनियों के लिए एक अच्छा कारण है, इसलिए आपको चेतावनी को दबाने के बजाय अपना कोड सुधारने का प्रयास करना चाहिए। प्रभावी जावा से उद्धरण, दूसरा संस्करण:

प्रत्येक अनचेक चेतावनी को हटा दें जो आप कर सकते हैं। यदि आप सभी चेतावनियों को खत्म करते हैं, तो आपको आश्वस्त किया जाता है कि आपका कोड टाइपएफ़ है, जो बहुत ही अच्छी बात है। इसका मतलब है कि आपको रनटाइम पर ClassCastException नहीं मिलेगा, और यह आपके आत्मविश्वास को बढ़ाता है कि आपका प्रोग्राम आपके इरादे से व्यवहार कर रहा है।

आप एक चेतावनी को खत्म नहीं कर सकते हैं, और आप को साबित कर सकते हैं कि कोड है कि चेतावनी उकसाया typesafe है, तो (और उसके बाद ही) एक @SuppressWarnings("unchecked") टिप्पणी के साथ चेतावनी को दबाने। यदि आप चेतावनी को पहले बिना साबित करते हैं कि कोड टाइपएफ़ है, तो आप केवल सुरक्षा की झूठी भावना दे रहे हैं। कोड किसी भी चेतावनी को उत्सर्जित किए बिना संकलित कर सकता है, लेकिन यह अभी भी रनटाइम पर ClassCastException फेंक सकता है। यदि, हालांकि, आप अनचेक चेतावनियों को अनदेखा करते हैं जिन्हें आप सुरक्षित रखना चाहते हैं (उन्हें दबाने के बजाए), तो आप ध्यान नहीं देंगे जब एक नई चेतावनी फसलों को वास्तविक समस्या का प्रतिनिधित्व करता है। नई चेतावनी उन सभी झूठे अलार्मों के बीच खो जाएगी जो आपने चुप नहीं की थीं।

बेशक, ऊपर दिए गए कोड के साथ चेतावनियों को खत्म करना हमेशा आसान नहीं होता है। अपना कोड देखे बिना, यह बताने का कोई तरीका नहीं है कि इसे सुरक्षित कैसे किया जाए।

+0

कैसे इस अनियंत्रित कलाकारों के बारे में: 'FoodBag bag2 = नए FoodBag ();' ' ((FoodBag ) bag2) .setFood (नई CheeseSandwich());' एक करने के लिए एक सामान्य प्रकार से सामान्य प्रकार? – Datoraki

+0

@Datoraki, क्या आप अपने प्रश्न के साथ अधिक विशिष्ट हो सकते हैं? –

+19

-1 क्योंकि उत्तर प्रश्न का हिस्सा "कास्ट कैसे जांचें" को संबोधित नहीं करता है। ठीक है, हम जानते हैं कि हमें कास्ट की जांच करनी चाहिए, ** हम इसे कैसे करते हैं? – Mike

39

पीटर क्या लिखा है के बारे में अधिक ellaborate करने के लिए:

सामान्य प्रकार के गैर सामान्य प्रकार से लेती है, क्रम में ठीक काम कर सकते हैं क्योंकि सामान्य मापदंडों संकलन के दौरान मिट रहे हैं, तो हम एक वैध कलाकारों के साथ छोड़ दिया जाता है। हालांकि, कोड पैरामीटर के संबंध में गलत धारणा के कारण बाद में एक अप्रत्याशित ClassCastException के साथ कोड विफल हो सकता है। उदाहरण के लिए:

List l1 = new ArrayList(); 
l1.add(33); 
ArrayList<String> l2 = (ArrayList<String>) l1; 
String s = l2.get(0); 

अनियंत्रित चेतावनी लाइन 3 में इंगित करता है कि संकलक अब और प्रकार सुरक्षा की गारंटी करने के लिए, इस अर्थ में कि एक अप्रत्याशित ClassCastException somewere बाद में occure सकता है सक्षम नहीं है। और यह लाइन 4 पर होता है, जो एक निहित कलाकार का प्रदर्शन करता है।

+5

यह स्वीकार्य उत्तर होना चाहिए – CodyBugstein

0

चेक किए गए कलाकारों के विपरीत एक अनचेक कास्ट, रनटाइम पर टाइप सुरक्षा की जांच नहीं करता है।

यहां तीसरे संस्करण के Consider typesafe heterogenous containers अनुभाग के आधार पर एक उदाहरण दिया गया है।"प्रभावी जावा" यहोशू बलोच द्वारा, लेकिन कंटेनर वर्ग की जानबूझकर टूट गया है - यह भंडार और गलत प्रकार देता है:

public class Test { 

    private static class BrokenGenericContainer{ 
     private final Map<Class<?>, Object> map= new HashMap<>(); 

     public <T> void store(Class<T> key, T value){ 
      map.put(key, "broken!"); // should've been [value] here instead of "broken!" 
     } 

     public <T> T retrieve(Class<T> key){ 
//   return key.cast(map.get(key)); // a checked cast 
      return (T)map.get(key);  // an unchecked cast 
     } 

    } 

    public static void main(String[] args) { 
     BrokenGenericContainer c= new BrokenGenericContainer(); 
     c.store(Integer.class, 42); 
     List<Integer> ints = new ArrayList<>(); 
     ints.add(c.retrieve(Integer.class)); 
     Integer i = ints.get(0); 
    } 

} 


retrieve() एक अनियंत्रित डाली का उपयोग करता है - (T)map.get(key) - इस कार्यक्रम चल रहा होगा ClassCastException पर Integer i = ints.get(0) लाइन पर होता है। क्योंकि वास्तविक प्रकार रनटाइम पर चेक नहीं किया गया था retrieve() विधि को पूरा करेगा:

Exception in thread "main" 
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer 
    at Test.main(Test.java:27) 


लेकिन retrieve() का उपयोग करता है, तो एक डाली को चेक किया था - key.cast(map.get(key)) - इस कार्यक्रम ClassCastException को बढ़ावा मिलेगा चल key.cast(map.get(key)) लाइन में होने वाली है, क्योंकि चेक की गई कास्ट यह पता लगाएगी कि प्रकार गलत है और अपवाद फेंक दें। retrieve() विधि पूरा हो जाएगा नहीं:

Exception in thread "main" java.lang.ClassCastException: 
              Cannot cast java.lang.String to java.lang.Integer 
    at java.lang.Class.cast(Class.java:3369) 
    at Test$BrokenGenericContainer.retrieve(Test.java:16) 
    at Test.main(Test.java:26) 

लिटिल अंतर यह लग सकता है, लेकिन अनियंत्रित कलाकारों के साथ मामले में, एक String सफलतापूर्वक एक List<Integer> में अपना रास्ता बनाया। असली दुनिया के अनुप्रयोगों में, इसके परिणाम हो सकते हैं ... अच्छा, गंभीर। चेक की गईस्ट के मामले में, टाइप मिस्चैच जितनी जल्दी हो सके खोजा गया था।


चेतावनी अनियंत्रित डाले बचने के लिए, @SuppressWarnings("unchecked") इस्तेमाल किया जा सकता है, अगर प्रोग्रामर वास्तव में यकीन है कि विधि सुरक्षित वास्तव में है। बेहतर विकल्प जेनेरिक का उपयोग करना और संभव होने पर चेक को चेक करना है।

के रूप में यहोशू बलोच कहते हैं,

... अनियंत्रित चेतावनी महत्वपूर्ण हैं। उन्हें अनदेखा मत करो।


पूर्णता के लिए, this ग्रहण बारीकियों के साथ जवाब से संबंधित है।