2011-01-11 6 views
7

मैंने हाल ही में मानक संग्रह प्रकारों के गतिशील रूप से टाइपएफ़ दृश्य बनाने के लिए Collection.checkedMap कार्यों के परिवार के लिए जावाडोक में ठोकर खाई। यह मानते हुए कि वे अपेक्षाकृत सामान्य प्रोग्रामर त्रुटि का निदान करने वाले संग्रहों के शीर्ष पर सुरक्षा की एक और परत जोड़ते हैं, मुझे लगता है कि वे अधिक लोकप्रिय होंगे। कुछ कारणों से, हालांकि, मैंने बड़ी जावा परियोजनाओं में काम किया है, मैंने उन्हें एक बार उपयोग नहीं देखा है।क्यों संग्रह नहीं हैं .checkedMap और दोस्तों ने अधिक सामान्य रूप से उपयोग किया?

मेरा प्रश्न यह है: क्या कोई विशेष कारण है कि जावा प्रोग्रामर इन चेक किए गए रैपरों का अधिक बार उपयोग नहीं करते हैं? या क्या यह उनके अस्तित्व के ज्ञान की कमी/कमी की कमी है?

संपादित करें: मेरे प्रश्न को स्पष्ट करने के लिए, संग्रह के सामान्य संस्करणों में अभी भी प्रकार-असुरक्षित कार्य शामिल हैं। Map का containsKey, containsValue, remove, और get सभी उदाहरण के लिए Object पर काम करते हैं। मेरा मुख्य सवाल यह है कि, इस प्रकार की असुरक्षितता को देखते हुए, अधिकतर लोग रनटाइम प्रकार के उल्लंघनों का निदान करने के लिए चेक किए गए कार्यान्वयन का उपयोग क्यों नहीं करते हैं।

उत्तर

13

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

नतीजतन, इन विधियों का उपयोग केवल एपीआई डिजाइनरों के संदर्भ में वास्तव में दिलचस्प है जो लाइब्रेरी के उपयोगकर्ताओं पर भरोसा नहीं करते हैं, और मानचित्र का उपयोग कर उपयोगकर्ताओं से स्वयं या उपयोगकर्ताओं को सुरक्षित रखना चाहते हैं ।

यहाँ यह की कमी है: यदि आपके कोड कच्चे प्रकार चेतावनी या किसी अनियंत्रित रूपांतरण/प्रकार बिना चेतावनी के संकलित हैं, तो आप गारंटी कि checked* तरीकों आप कोई लाभ नहीं देते हैं; वे केवल एक रनटाइम हिट हैं।

संपादित

आप समापन जा सकता है कि remove, get, आदि के बाद से एक Object पर काम करते हैं, वे किसी भी तरह टाइप-असुरक्षित कर रहे हैं लगता है। वो नहीं हैं। उन तरीकों में से कोई भी मानचित्र में अपना ऑपरेंड स्टोर नहीं करेगा, इसलिए आप निश्चित रूप से मानचित्र की प्रकार की सुरक्षा से समझौता नहीं कर रहे हैं। वे विधियां एक मुख्य कारण के लिए ऑब्जेक्ट लेती हैं: पिछली संगतता के लिए। उसी वर्ग का पालन करने के लिए आवश्यक किसी भी सख्त आवश्यकता की आवश्यकता नहीं थी। उदाहरण के लिए, यदि कक्षा ए का एक उदाहरण और कक्षा बी का एक उदाहरण किसी अन्य के बराबर हो सकता है, तो a को मानचित्र में डालें और फिर remove(b)पर कॉल करनाa मैपिंग को हटा दें।

बैकवर्ड संगतता को संरक्षित करने के लिए जेनेरिक जोड़े जाने के बाद इस व्यवहार को समर्थित करने की आवश्यकता है। इस प्रकार वे remove(K) जैसे इंटरफ़ेस को अपडेट नहीं कर सके क्योंकि मौजूदा कोड पूरी तरह से अलग वर्ग के उदाहरण दिए गए मैपिंग को हटाने में सक्षम होने पर निर्भर हो सकता है। हालांकि यह असुरक्षित नहीं है, और मानचित्र के चेक किए गए संस्करण का उपयोग करके इस व्यवहार को थोड़ी सी में बदल नहीं आता है।

+0

मुख्य कारण यह है कि ऐसा लगता है कि इन कंटेनरों को रखना एक अच्छा विचार हो सकता है, हालांकि, मानचित्र के .put() जैसी चीजों के लिए है, जो कि के बजाए ऑब्जेक्ट लेता है (उदाहरण के लिए, मानचित्र )। यह वास्तव में गलत तरीके से किसी वस्तु को किसी मानचित्र में जोड़ने के लिए जेनेरिकों के दुरुपयोग की तरह प्रतीत नहीं होता है; यह एक प्रोग्रामर त्रुटि है। – templatetypedef

+2

@templatetypedef: मुझे यकीन नहीं है कि आपका क्या मतलब है। मानचित्र का 'put'' put (K, V) 'के रूप में निर्दिष्ट किया गया है। यदि आप जेनेरिक का उपयोग कर रहे हैं तो आप किसी भी पुराने ऑब्जेक्ट को मानचित्र में नहीं डाल सकते हैं। –

+0

@ मार्क पीटर्स- मेरी गलती; मेरा मतलब था 'put', जो' के' के बजाय 'ऑब्जेक्ट' लेता है। 'निकालें' वही तरीका है, जैसा कि 'शामिल है' और 'युक्त वैल्यू' है। – templatetypedef

0

रिट्रेक्ट: निम्नलिखित राय गलत है। पिछड़े संगतता से परे कुछ अच्छे कारण हैं, क्यों किसी भी प्रकार के लुकअप इंडेक्स होना बेहतर है।

कोई दिव्य कारण नहीं है कि इन तरीकों को E के बजाय Object क्यों लेना चाहिए। असली दुनिया के कार्यक्रमों में यदि एक गैर-ई वस्तु पारित होती है, तो यह लगभग निश्चित रूप से एक अनुप्रयोग बग है।अधिकांश संस्करणों में ऑब्जेक्ट संस्करण से ई संस्करण एपीआई बेहतर होगा। और मैं कहता हूं कि सूर्य ने यहां एक गलती की है। कोई पिछड़ा संगतता मुद्दा नहीं है, क्योंकि जेनेरिक एपीआई एक ब्रांड नई एपीआई है।

सौभाग्य से मेरा आईडीई (इंटेलिजे) मुझे चेतावनी देगा अगर मैं इन तरीकों से गैर-ई प्रकार पास करता हूं। स्टेटिक जांच किस प्रकार भाषा भाषा कहती है और कौन सा कंपाइलर करता है उससे परे धक्का दिया गया है।

+0

मैंने डी/वी नहीं किया, लेकिन पीछे की संगतता समस्या है, और जेनेरिक संग्रह एपीआई "ब्रांड नया" नहीं थे, उन्होंने मौजूदा संग्रह API को दोबारा हटा दिया। –

+0

@ मार्क-पेटर्स पुट (के, वी) भी आपकी "पिछड़ा संगतता" तोड़ता है क्योंकि पुरानी विधि में बाधा नहीं होती है। लेकिन नहीं, इस तरह की कोई संगतता समस्या नहीं है, क्योंकि सामान्य इंटरफ़ेस का उपयोग करने वाला कोई भी कोड नया कोड है, और वे नई बाधाओं को स्वीकार करते हैं, और यदि वे पुट (के, वी) स्वीकार कर सकते हैं, तो वे निकालें (के) स्वीकार कर सकते हैं। वास्तव में सभी लोग निकालने (ऑब्जेक्ट) को हटाने के बजाय (के) को हटाना चाहते हैं। अब मेरी बात वापस दो। – irreputable

+0

यह एक स्रोत कोड या बाइटकोड संगतता के बारे में नहीं है। यह 'निकालें (ऑब्जेक्ट) 'और इसी तरह के तरीकों के अनुबंध के बारे में है। जब उन्होंने जेनेरिक के साथ संग्रह को दोबारा हटा दिया, तो 'निकालें (ऑब्जेक्ट)' को हटाने के लिए (के) 'को अपडेट करने के लिए उन्हें विधि के विनिर्देश को बदलना होगा (जैसा कि, यह * कार्यात्मक रूप से * क्या करता है)। –

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

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