जब आप स्ट्रॉन्ग () और हैशकोड () में किसी ऑब्जेक्ट के "ऑब्जेक्ट संदर्भ" को जावा में कैसे प्राप्त कर लेते हैं, तो उसे अस्वीकृत कर दिया गया है?


106

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

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

उदाहरण की स्थिति: एक बहु-थ्रेडेड एप्लिकेशन चलाना, जहां मैं (विकास के दौरान) यह जांचना चाहता हूं कि सभी थ्रेड्स संसाधन ऑब्जेक्ट के समान उदाहरण का उपयोग करते हैं या नहीं।


1
इस पर निर्भर करते हुए कि आप इसे बिल्कुल भी कर सकते हैं ... == जाने का तरीका है ... लेकिन मुझे नहीं पता कि प्रश्न में कोड कैसे है। फिर से हैशकोड आपके द्वारा किए जा रहे काम के लिए ठीक है, लेकिन यह इस बात पर निर्भर करता है कि लाइब्रेरी कैसे लागू होती है।
टोफूबीर

यह वास्तव में एक अच्छा सवाल है।
झांग जियांग जियांग

जवाबों:


108

आप वास्तव में इसके साथ क्या करने की योजना बना रहे हैं (आप क्या करना चाहते हैं इससे आपको क्या फर्क पड़ता है कि आपको कॉल करने की आवश्यकता होगी)।

hashCode, जैसा कि JavaDocs में परिभाषित किया गया है, कहते हैं:

जितना अधिक व्यावहारिक रूप से व्यावहारिक है, क्लास ऑब्जेक्ट द्वारा परिभाषित हैशकोड विधि अलग-अलग वस्तुओं के लिए अलग-अलग पूर्णांक लौटाती है। (यह आमतौर पर ऑब्जेक्ट के आंतरिक पते को पूर्णांक में परिवर्तित करके कार्यान्वित किया जाता है, लेकिन जावा ™ प्रोग्रामिंग भाषा द्वारा इस कार्यान्वयन तकनीक की आवश्यकता नहीं है।)

तो अगर आप hashCode()यह पता लगाने के लिए उपयोग कर रहे हैं कि क्या यह मेमोरी में एक अनोखी वस्तु है जो इसे करने का एक अच्छा तरीका नहीं है।

System.identityHashCode निम्नलिखित कार्य करता है:

दिए गए ऑब्जेक्ट के लिए समान हैश कोड लौटाता है क्योंकि डिफ़ॉल्ट विधि hashCode () द्वारा वापस किया जाएगा, चाहे दिया गया ऑब्जेक्ट हैशकोड () को ओवरराइड करता है या नहीं। शून्य संदर्भ के लिए हैश कोड शून्य है।

जो, आप जो कर रहे हैं, उसके लिए लगता है कि आप क्या चाहते हैं ... लेकिन आप जो करना चाहते हैं वह इस बात पर निर्भर नहीं हो सकता है कि लाइब्रेरी कैसे लागू होती है।


6
मैं कोड में मूल्य पर कार्य नहीं कर रहा हूं। के रूप में जनसंपर्क। मेरा प्रश्न संपादित करें, मैं केवल एक निश्चित स्थिति के डीबगिंग उद्देश्यों के लिए इसका उपयोग करता हूं। यही कारण है कि मुझे लगता है कि मेरा उत्तर उचित है, लेकिन मैं आपको एक व्यावहारिक उत्तर के लिए +1 देता हूं।
निकोलई

1
संभावना है कि यह हमेशा वही करेगा जो आप चाहते हैं - लेकिन यह कुछ वीएम पर टूट सकता है।
टोफूबीर

यह किसी भी उचित वीएम पर टूट जाएगा (यानी पहचान हैशकोड आवश्यक रूप से अद्वितीय नहीं होगा)। पहचान
हाशकोड

जैसा कि उल्लेख किया गया है, पते के आधार पर हैशकोड की कोई ग्वारेंटी नहीं है। मैंने WAS के अंदर IBM VM में एक ही आईडी के साथ कई ऑब्जेक्ट्स देखे हैं।
रॉबिन

"यह आमतौर पर ऑब्जेक्ट के आंतरिक पते को पूर्णांक में परिवर्तित करके कार्यान्वित किया जाता है" एक गुरेंटी नहीं, लेकिन डिफ़ॉल्ट रूप से I से। एस = "हेलो" और टी = "हेलो" जैसी चीजें शायद एस और टी में समान पहचान होती हैं। वॉशकोड जैसा कि वे वास्तव में एक ही वस्तु हैं।
टोफूबीर

50

यह मैंने इसे कैसे हल किया:

Integer.toHexString(System.identityHashCode(object));

5
यह वास्तव में सही नहीं है, क्योंकि कई वस्तुएं समान पहचान वापस कर सकती हैं।
रॉबिन

2
क्या यह सच नहीं है कि एक ही पहचान वाले दो ऑब्जेक्ट (संदर्भ) एक ही वस्तु हैं? ओपी यही चाहता है
बेजरोजो

3
नहीं, यह सच नहीं है। यह बहुत संभावना है, लेकिन गारंटी नहीं है क्योंकि कल्पना एल्गोरिथ्म को परिभाषित नहीं करती है।
रॉबिन

8

डबल समतुल्य ==हमेशा वस्तु पहचान के आधार पर जांच करेगा, भले ही वस्तुओं के हैशकोड या बराबर के कार्यान्वयन के बावजूद। बेशक - सुनिश्चित करें कि आप जिस वस्तु संदर्भ की तुलना कर रहे हैं वह volatile(1.5+ JVM में) है।

यदि आपके पास वास्तव में मूल वस्तु होनी चाहिए परिणाम (हालांकि यह आपके उदाहरण उपयोग-मामले के लिए सबसे अच्छा समाधान नहीं है), कॉमन्स लैंग लाइब्रेरी में एक विधि ObjectUtils.identityToString (ऑब्जेक्ट) है जो वह करेगी जो आप चाहते हैं। JavaDoc से:

public static java.lang.String identityToString(java.lang.Object object)

यदि कोई वर्ग खुद को आघात करने से आगे नहीं बढ़ता है, तो वस्तु द्वारा उत्पादित होने वाली स्ट्रैसिंग हो जाती है। अशक्त वापस आ जाएगा।

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "java.lang.String@1e23"
 ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"

1
आप जावा 7 का उपयोग कर रहे हैं, तो आप का उपयोग करना चाहिए java.util.Objects
noahlz

5

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

रिकॉर्ड के लिए, मैंने एक WAS सर्वर में चल रहे IBM VM में समान डिफ़ॉल्ट हैशकोड के साथ कई वस्तुओं का अनुभव किया है। हमारे पास एक ऐसी खराबी थी जहां दूर के कैश में रखी जाने वाली वस्तुओं को इस वजह से अधिलेखित कर दिया जाएगा। यह उस समय मेरे लिए एक आंख खोलने वाला था क्योंकि मैंने डिफ़ॉल्ट हैशकोड के रूप में अच्छी तरह से वस्तुओं का पता संबोधित किया था।


2

अपने सभी उदाहरणों के लिए एक अद्वितीय आईडी जोड़ें, अर्थात

public interface Idable {
  int id();
}

public class IdGenerator {
  private static int id = 0;
  public static synchronized int generate() { return id++; }
}

public abstract class AbstractSomething implements Idable {
  private int id;
  public AbstractSomething () {
    this.id = IdGenerator.generate();
  }
  public int id() { return id; }
}

AbstractSomething से विस्तार और इस संपत्ति क्वेरी। एक एकल वीएम के अंदर सुरक्षित रहेगा (मान लीजिए कि स्टैटिक्स के आसपास पाने के लिए क्लास लोडर के साथ कोई खेल नहीं खेल रहा है)।


मैं शायद इस परिदृश्य में एटोमिकइंटरियर का उपयोग करूंगा - इसका उच्चतर थ्रूपुट है क्योंकि सिंक्रोनाइज़ेशन की आवश्यकता नहीं है और इसके द्वारा प्रदान की गई देशी परमाणु मेमोरी ऑपरेशन का उपयोग करता हैsun.misc.Unsafe
RAnders00

1

हम स्ट्रिंग का संदर्भ प्राप्त करने के लिए बस ऑब्जेक्ट क्लास के कोड से कोड कॉपी कर सकते हैं

class Test
{
  public static void main(String args[])
  {
    String a="nikhil";     // it stores in String constant pool
    String s=new String("nikhil");    //with new stores in heap
    System.out.println(Integer.toHexString(System.identityHashCode(a)));
    System.out.println(Integer.toHexString(System.identityHashCode(s)));
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.