2012-09-16 22 views
8

यदि Map की कुंजी के हिस्से के रूप में Class<T> का उपयोग करने की आवश्यकता है तो hashCode और equals को परिभाषित करने का सही तरीका क्या है?
एक Class<T>Object से लोगों को जो संदर्भ समानता के लिए जाँच करें और hashCode के रूप में स्मृति पता वापस लेकिन मेरे मन में यह स्पष्ट क्या equals की सार्थक परिभाषा और एक Class<T> की hashCode परिभाषा नहीं है इनहेरिट करती है।
क्या मुझे वास्तविक उदाहरण के तरीकों का उपयोग करने के लिए उदाहरण के लिए theClass.getClass().hashCode(); का उपयोग करना चाहिए (जहां हमारे पास Class<T> theClass; है)?
लेकिन ऐसा करने के लिए यह सही काम प्रतीत नहीं होता है।
में उदाहरण के लिए javadocClass<T> के लिए:हैशकोड को अर्थपूर्ण रूप से परिभाषित करने के लिए और java.lang.Class <T> के लिए बराबर कैसे करें?

हर सरणी भी एक वर्ग है कि एक वर्ग उद्देश्य यह है कि एक ही तत्व प्रकार के साथ सभी सरणियों और आयामों की संख्या से साझा किया जाता है के रूप में देखा जा सकता है के अंतर्गत आता है

तो यह कुछ मामलों में एक ही Class<T> वस्तुओं के बीच साझा किया जाता है में है? तो पालन करने का तरीका क्या होगा? संदर्भ समानता का उपयोग करने के लिए शायद theClass.hashCode() और theClass.equals() का उपयोग करें? यहां बिल्कुल यकीन नहीं है।

+0

परिभाषित करने के लिए कुछ भी नहीं है, क्योंकि हैशकोड और बराबर पहले ही कार्यान्वित किए गए हैं, और मुझे यह समझने में कठिनाई होती है कि आप यह कार्यान्वयन क्यों बदलेंगे और यह भी कठिन समय लग रहा है। –

+0

@JensSchauder: स्वचालित रूप से 'हैशकोड' और 'बराबर' उत्पन्न करने के लिए ग्रहण का उपयोग करके यह चेतावनी दी गई है कि 'हैशकोड' और 'बराबर' को 'कक्षा' के लिए परिभाषित नहीं किया गया है। इससे मुझे चिंता है कि यह एक वैध चेतावनी है और मैं इसके बारे में कुछ करना चाहिए। – Cratylus

+0

मुझे नहीं पता कि आप क्या करने की कोशिश कर रहे हैं, लेकिन 'कक्षा' एक वर्ग है जो जावा का हिस्सा है। आप इसके लिए कुछ भी लागू नहीं कर सकते हैं। स्रोत फ़ाइल का पूरा नाम क्या है जहां आप हैशकोड जोड़ने और बराबर करने का प्रयास करते हैं? –

उत्तर

8

java.lang.Object से hashCode और equalsjava.lang.Class inherits के कार्यान्वयन सार्थक और आमतौर पर उचित है, के रूप में एक वर्ग के सभी उदाहरणों, getClass() से हीClass वस्तु लौटने के लिए गारंटी दी जाती है यानी

new Integer(2).getClass() == new Integer(3).getClass(); 

यह कुछ हद तक है दस्तावेज़ों में दफनाया; javadoc of getClass() लिखते हैं:

रिटर्न:

कक्षा उद्देश्य यह है कि इस वस्तु के क्रम वर्ग का प्रतिनिधित्व करता है।

भी देखें:

Literals, जावा ™ भाषा विशिष्टता की धारा 15.8.2।

That section लिखते हैं: कक्षा वस्तु को

एक वर्ग शाब्दिक मूल्यांकन करता नामित प्रकार (या शून्य के लिए) के रूप में परिभाषित वर्ग लोडर द्वारा परिभाषित के लिए (§12.2) वर्तमान उदाहरण के वर्ग के ।

और section 12.2 लिखते हैं:

अच्छी तरह से व्यवहार वर्ग लोडर इन गुणों को बनाए रखने:

  • एक ही नाम को देखते हुए, एक अच्छा वर्ग लोडर हमेशा एक ही वर्ग ऑब्जेक्ट प्रदान।
  • ...

एक दुर्भावनापूर्ण वर्ग लोडर इन गुणों का उल्लंघन कर सकता है। हालांकि, यह टाइप सिस्टम की सुरक्षा को कमजोर नहीं कर सका, क्योंकि जावा वर्चुअल मशीन इसके खिलाफ गार्ड करता है।

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

+0

इस पर साइड नोट: टोमकैट जैसे अनुप्रयोग एक पदानुक्रमित क्लासलोडर का उपयोग करते हैं और यह आपको काट सकता है। टॉमकैट अपने सभी एप्लिकेशन को अपने स्वयं के क्लासलोडर स्टैक देता है। –

0

विधि String getName()अद्वितीय कक्षा का स्ट्रिंग प्रतिनिधित्व देता है। यदि आपका प्रोग्राम एक से अधिक क्लासलोडर का उपयोग नहीं करता है तो आप समान स्ट्रिंग के रूप में बराबर/हैशकोड के लिए इस स्ट्रिंग का उपयोग कर सकते हैं।

+0

लेकिन मैं 'मानचित्र , टी> नहीं करता हूं। मेरा सवाल यह है कि 'कक्षा ' एक कुंजी का ** भाग ** है। कुंजी स्वयं ही नहीं – Cratylus

+0

@Cratylus उत्तर वही है; आप getName() का उपयोग करते हैं जो क्लास ऑब्जेक्ट का एक अद्वितीय स्ट्रिंग प्रतिनिधित्व देता है; आप इस स्ट्रिंग का उपयोग हैशिंग/बराबर में करते हैं जैसे कि यह एक स्ट्रिंग इंस्टेंस फ़ील्ड था। – m3th0dman