2015-05-21 4 views
12

में डालकर मैं समझने की कोशिश कर रहा हूं कि java.util.Properties को इस तरह क्यों लागू किया गया था। इसमें दो इंटरफेस हैं: getProperty/setProperty जो केवल स्ट्रिंग स्वीकार करता है, और डाल/प्राप्त करता है जो किसी ऑब्जेक्ट को मान के रूप में स्वीकार करता है। ये दो इंटरफेस ओवरलैपिंग प्रतीत होते हैं, इसलिए getProperty() का उपयोग करके पुट() के साथ जोड़ा गया स्ट्रिंग पुनर्प्राप्त किया जा सकता है।वस्तुओं को java.util.Properties

इस अजीब हाइब्रिड इंटरफ़ेस के साथ कुछ समस्याएं प्रतीत होती हैं। एक स्ट्रिंग प्रॉपर्टी को ओवरराइड करने वाली ऑब्जेक्ट को स्ट्रिंग मान को साफ़ करने का दुष्प्रभाव होता है, जो getProperty परिणाम के रूप में शून्य उत्पन्न करता है। एक पूर्णांक जोड़ना, या कुछ अन्य मान जिसमें एक साधारण स्ट्रिंग अनुवाद है, वास्तविक संपत्ति मान होने के रूप में गलत समझा जा सकता है (लेकिन एक संपत्ति के रूप में यह हमेशा शून्य है)।

मेरा प्रश्न है: क्या इसके लिए एक वास्तविक, व्यावहारिक कारण है? या क्या यह आधा बेक्ड कार्यान्वयन है जैसा मुझे संदेह है?

+0

मैं इसे वापस नहीं कर सकता, लेकिन मुझे दृढ़ता से संदेह होगा कि समस्या पीछे की संगतता है। 'गुण'' हैशटेबल 'बढ़ाता है, जो जेनेरिक से पहले पुरानी कक्षा है; इसका मतलब है कि यदि आपके पास 'Properties' था, तो आप' Properties.put (जो भी हो, जो भी हो) कह सकते थे। जब जेनेरिक साथ आए, तो जावा लोग कोड को पीछे संगत रखना चाहते थे, जिसका अर्थ है कि यह 'हैशटेबल <ऑब्जेक्ट, ऑब्जेक्ट>' बढ़ाता है। – yshavit

+0

'गुण'' हैशटेबल 'का उप-वर्ग है, जिसमें 'get' /' put' के ओवरराइड नहीं हैं, इसलिए व्यवहार। 'getProperty' /' setProperty' 'get' /' put' के टाइप किए गए संस्करण हैं। यह इतिहास का मामला है और छुपा नहीं है। –

उत्तर

10

Joshua BlochProperties के मामले में [अध्याय 4 से ] में Effective Java

स्पष्ट रूप से यह उल्लेख है, डिजाइनरों का इरादा है कि केवल तार कुंजी और मूल्यों के रूप में अनुमति दी जानी है, लेकिन अंतर्निहित Hashtable के लिए सीधी पहुँच की अनुमति देता है इस आविष्कार का उल्लंघन किया जाना चाहिए। एक बार इस आविष्कार का उल्लंघन हो जाने के बाद, गुण API (load और store) के अन्य हिस्सों का उपयोग करना अब संभव नहीं है। जब तक इस समस्या की खोज हुई, तब तक इसे ठीक करने में बहुत देर हो गई क्योंकि ग्राहक नॉनस्ट्रिंग कुंजी और मूल्यों के उपयोग पर निर्भर थे।

वह पाठ विरासत पर संरचना का उपयोग करने के संदर्भ में है। वह मूल रूप से विरासत के बजाए रचना का उपयोग करने के उदाहरण के रूप में इसका उपयोग कर रहा है। यदि Properties ने Map को विस्तारित करने के बजाय लपेट लिया है, तो यह String को चाबियाँ और मानों के रूप में उपयोग करने के आविष्कार को लागू कर सकता था।

तो जवाब है: यह एक निरीक्षण था।

+1

इस उत्तर का चयन करना क्योंकि यह बताता है कि इसे "अन्य तरीकों का उपयोग न करें" से कहीं अधिक क्यों लागू किया गया था। साइड नोट के रूप में, जावा मेल एपीआई कस्टम एसएसएल सॉकेट फैक्ट्री को कॉन्फ़िगर करने के लिए डिज़ाइन द्वारा इसका उपयोग करता है। ओह जावा, प्यार-नफरत संबंध हमारे पास है। –

2

सरकारी दस्तावेजों का कहना है

क्योंकि गुण Hashtable, डाल से विरासत और putAll तरीकों एक गुण वस्तु के लिए लागू किया जा सकता है। उनका उपयोग दृढ़ता से निराश होता है क्योंकि वे कॉलर को उन प्रविष्टियों को सम्मिलित करने की अनुमति देते हैं जिनकी चाबियाँ या मान स्ट्रिंग नहीं हैं। इसके बजाय सेटप्रोपर्टी विधि का उपयोग किया जाना चाहिए। यदि स्टोर या सेव विधि को "समझौता" गुण ऑब्जेक्ट पर कॉल किया जाता है जिसमें गैर-स्ट्रिंग कुंजी या मान होता है, तो कॉल विफल हो जाएगी। इसी तरह, संपत्ति नाम या सूची विधि को कॉल विफल हो जाएगा यदि इसे "समझौता" गुण ऑब्जेक्ट पर कहा जाता है जिसमें गैर-स्ट्रिंग कुंजी होती है।

http://docs.oracle.com/javase/8/docs/api/java/util/Properties.html

5

put और get तक पहुंच Hashtable का ही विस्तार किया जा रहा है Properties का एक परिणाम है, और दो विधि नहीं किया जाना चाहिए (लेकिन कार्यान्वयन से सुपर क्लास में अपने सार्वजनिक उपयोग की वजह से छुपाया नहीं जा सकता)।

Javadocs कारण है कि आप उन तरीकों का उपयोग नहीं करना चाहिए के बारे में एक अच्छा टिप्पणी है, और बजाय केवल उपयोग तार चाहिए:

Hashtable से Properties इनहेरिट करती है, put और putAll तरीकों एक Properties करने के लिए लागू किया जा सकता है वस्तु। उनका उपयोग दृढ़ता से निराश होता है क्योंकि वे कॉलर को उन प्रविष्टियों को सम्मिलित करने की अनुमति देते हैं जिनकी चाबियाँ या मान Strings नहीं हैं। इसके बजाय setProperty विधि का उपयोग किया जाना चाहिए। यदि store या save विधि को "समझौता" Properties ऑब्जेक्ट पर कॉल किया जाता है जिसमें गैर-String कुंजी या मान होता है, तो कॉल विफल हो जाएगी। इसी प्रकार, propertyNames या list विधि पर कॉल विफल हो जाएगा यदि इसे "समझौता" Properties ऑब्जेक्ट पर कॉल किया जाता है जिसमें गैर- String कुंजी होती है।

@yshavit नोटों के रूप में, यह Properties के लिए और अधिक समझ बनाने के दो वस्तुओं की एक hashtable से Hashtable<String, String> विस्तार करने के लिए चाहते हैं, लेकिन इस संभावना से किसी के साथ get/put का उपयोग कर किसी भी प्रोग्राम के रूप में, पश्च संगतता बनाए रखने के लिए बनाया एक निर्णय था गैर-स्ट्रिंग ऑब्जेक्ट्स इस तरह के बदलाव से टूट गए होंगे।

+0

लेकिन यह प्रश्न के एक महत्वपूर्ण हिस्से को संबोधित नहीं करता है, यही कारण है कि 'स्ट्रिंग' के बजाय' ऑब्जेक्ट 'पर प्राप्त/पॉट विधियां काम करती हैं।यही कारण है कि, यह 'हैशटेबल <ऑब्जेक्ट, ऑब्जेक्ट>' क्यों नहीं बढ़ाता है? (उपर्युक्त मेरी टिप्पणी के अनुसार, मुझे दृढ़ता से संदेह है कि यह पिछड़ा संगतता के लिए है - लेकिन मेरे पास विशिष्ट सबूत नहीं हैं।) – yshavit

+0

@yshavit अच्छा नोट; मैं मानता हूं कि यह लगभग पिछड़ा संगतता के लिए लगभग निश्चित रूप से है, और मैंने जवाब में ऐसा नोट जोड़ा है। – Vulcan

0

Java Docs

क्योंकि गुण Hashtable, पुट और putAll तरीकों से विरासत से एक गुण वस्तु के लिए लागू किया जा सकता है।उनका उपयोग दृढ़ता से निराश है क्योंकि वे कॉलर को उन प्रविष्टियों को सम्मिलित करने की अनुमति देते हैं जिनकी चाबियाँ या मान स्ट्रिंग नहीं हैं। इसके बजाय सेटप्रोपर्टी विधि का उपयोग किया जाना चाहिए। यदि स्टोर या सेव विधि को "समझौता" गुण ऑब्जेक्ट पर कॉल किया जाता है जिसमें गैर-स्ट्रिंग कुंजी या मान होता है, तो कॉल विफल हो जाएगी। इसी तरह, संपत्ति के लिए कॉल नाम या सूची विधि विफल हो जाएगी यदि इसे "समझौता" गुण ऑब्जेक्ट पर कॉल किया गया है जिसमें गैर-स्ट्रिंग कुंजी है।

0

PropertiesHashtable फैली हुई है, तो आप उपयोग कर सकते हैं Properties कहीं भी आप एक Hashtable उपयोग कर सकते हैं।

Hashtable कक्षा है जहां get() और put() फ़ंक्शन आ रहे हैं।

0

put(key, value) और get(key)PropertiesHashtable को दिन में वापस बढ़ाने के लिए एक संदिग्ध निर्णय के बने रहने वाले हैं। यह व्यवहार परिवर्तन नहीं हो सकता है क्योंकि यह पिछली संगतता को तोड़ देगा, लेकिन एपीआई दस्तावेज समेत किसी भी आधा सभ्य शैली मार्गदर्शिका, इन विधियों का कभी भी उपयोग करने की सिफारिश नहीं करेगा।

0

जैसा कि अन्य ने कहा है, आपको केवल स्ट्रिंग्स के लिए इसका उपयोग करना होगा। किसी ऑब्जेक्ट को स्ट्रिंग के रूप में क्रमबद्ध करने और इसे पुनर्प्राप्त करने के तरीके हैं, लेकिन जाहिर है कि इसका अर्थ यह नहीं है। मैं समझता हूं कि यह वास्तव में कष्टप्रद है क्योंकि यह निकटतम है कि आप ऐप डेटा को सहेजने और पुनर्प्राप्त करने के क्रॉस-प्लेटफ़ॉर्म तरीके से प्राप्त कर सकते हैं। जहां तक ​​मुझे पता है कि उपयोगकर्ता से छिपे हुए फ़ोल्डर में तारों के अलावा अन्य चीज़ों को सहेजने का कोई आधिकारिक तरीका नहीं है, इस तथ्य के बावजूद कि अधिकांश ऑपरेटिंग सिस्टम में एपडाटा निर्देशिकाएं हैं।

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