जावा में चर का मेमोरी पता


139

कृपया नीचे दी गई तस्वीर पर एक नज़र डालें। जब हम newकीवर्ड के साथ जावा में एक ऑब्जेक्ट बनाते हैं, तो हमें ओएस से मेमोरी एड्रेस मिल रहा है।

जब हम लिखते हैं out.println(objName)तो हम आउटपुट के रूप में एक "विशेष" स्ट्रिंग देख सकते हैं। मेरे प्रश्न हैं:

  1. यह आउटपुट क्या है?
  2. यदि यह स्मृति पता है जो ओएस द्वारा हमें दिया गया है:

    a) मैं इस स्ट्रिंग को बाइनरी में कैसे बदल सकता हूं?

    ख) मुझे एक पूर्णांक चर पता कैसे मिल सकता है?

वैकल्पिक शब्द


5
अच्छी तरह से मैं नीचे मतदान नहीं कर रहा हूँ क्योंकि यह प्रश्न पर्याप्त रूप से स्पष्ट है, बस एक सुझाव जो आपको इसे पाठ में बनाना चाहिए ताकि लोग इसे खोज सकें
phunehehe

2
Sun.misc.Unsafe का उपयोग करके जावा ऑब्जेक्ट का पता प्राप्त करना संभव है। कार्यक्रम लिस्टिंग संदर्भ के लिए: javapapers.com/core-java/address-of-a-java-object
यूसुफ कुलंदई

बताया गया है कि वस्तु a1 और a2 के हैशकोड का हेक्साडेसिमल प्रतिनिधित्व
नवीन

जवाबों:


166

वह वर्ग नाम और System.identityHashCode () '@' वर्ण द्वारा अलग किया गया है। क्या पहचान हैश कोड का प्रतिनिधित्व करता है कार्यान्वयन-विशिष्ट है। यह अक्सर ऑब्जेक्ट का प्रारंभिक मेमोरी एड्रेस होता है, लेकिन समय के साथ VM द्वारा ऑब्जेक्ट को मेमोरी में स्थानांतरित किया जा सकता है। इसलिए (संक्षेप में) आप इस पर कुछ भी भरोसा नहीं कर सकते।

चरों की मेमोरी एड्रेस प्राप्त करना जावा के भीतर अर्थहीन है, क्योंकि JVM वस्तुओं को लागू करने और उन्हें फिट होने के लिए स्थानांतरित करने के लिए स्वतंत्र है (जैसा कि आपकी वस्तुएं कचरा संग्रह आदि के दौरान चारों ओर घूम सकती हैं)।

Integer.toBinaryString () आपको बाइनरी फॉर्म में पूर्णांक देगा।


33
एक और दिलचस्प बात यह है कि पहचान हैश कोड अद्वितीय होने की गारंटी नहीं है। उदाहरण के लिए, 64-बिट JVM में 2 ^ 32 पहचान हैश कोड हैं, लेकिन 2 ^ 64 मेमोरी पते हैं
एलेक्स जैस्मीन

11
असल में, पहचान का हैश कोड बदल नहीं सकता , अन्यथा हैशकोड () का अनुबंध उल्लंघन होगा।
मैट मैकनेरी

1
मैं इसका उपयोग लॉगिंग / डिबगिंग के लिए लॉग्स में निर्धारण के लिए कर रहा हूं जब ऑब्जेक्ट समान ऑब्जेक्ट के बजाय समान ऑब्जेक्ट की ओर इशारा कर रहे हैं। इन उद्देश्यों के identityHashcodeलिए अर्थहीन नहीं है, यह सिर्फ मूर्ख नहीं है। :)
स्लेज

@BrianAgnew: मैं जानना चाहता हूं -> दो ऑब्जेक्ट में एक ही हैशकोड क्यों होता है। मैं उलझन में हूं क्योंकि मैंने c या c ++ में सीखा है हर चर या वस्तु का अलग-अलग मेमोरी लोकेशन होता है। फिर जावा में एक ही हैशकोड के साथ दो वस्तुओं की पहचान या अंतर कैसे किया जा सकता है।
वेद प्रकाश

1
@VedPrakash ऑब्जेक्ट हैशकोड ऑब्जेक्ट्स को हैशेड संग्रह में संग्रहीत करने की अनुमति देता है। यदि आप दो अलग-अलग वस्तुओं में अंतर करना चाहते हैं, तो आप बस संदर्भ समानता का उपयोग कर सकते हैं
ब्रायन एग्न्यू

36

इसका उपयोग करना संभव है sun.misc.Unsafe: @Peter Lawrey से यह शानदार उत्तर देखें -> क्या एक संदर्भ पता प्राप्त करने का कोई तरीका है?

PrintAddresses के लिए इसके कोड का उपयोग करना ():

    public static void printAddresses(String label, Object... objects) {
    System.out.print(label + ": 0x");
    long last = 0;
    int offset = unsafe.arrayBaseOffset(objects.getClass());
    int scale = unsafe.arrayIndexScale(objects.getClass());
    switch (scale) {
    case 4:
        long factor = is64bit ? 8 : 1;
        final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor;
        System.out.print(Long.toHexString(i1));
        last = i1;
        for (int i = 1; i < objects.length; i++) {
            final long i2 = (unsafe.getInt(objects, offset + i * 4) & 0xFFFFFFFFL) * factor;
            if (i2 > last)
                System.out.print(", +" + Long.toHexString(i2 - last));
            else
                System.out.print(", -" + Long.toHexString( last - i2));
            last = i2;
        }
        break;
    case 8:
        throw new AssertionError("Not supported");
    }
    System.out.println();
}

मैंने यह परीक्षण स्थापित किया:

    //hashcode
    System.out.println("Hashcode :       "+myObject.hashCode());
    System.out.println("Hashcode :       "+System.identityHashCode(myObject));
    System.out.println("Hashcode (HEX) : "+Integer.toHexString(myObject.hashCode()));

    //toString
    System.out.println("toString :       "+String.valueOf(myObject));

    printAddresses("Address", myObject);

यहाँ उत्पादन है:

Hashcode :       125665513
Hashcode :       125665513
Hashcode (HEX) : 77d80e9
toString :       java.lang.Object@77d80e9
Address: 0x7aae62270

निष्कर्ष:

  • हैशकोड! = पता
  • .String = वर्ग @ HEX (हैशकोड)

13

यह ऑब्जेक्ट के "toString ()" कार्यान्वयन का आउटपुट है। यदि आपकी कक्षा स्ट्रींग () से आगे निकल जाती है, तो यह पूरी तरह से कुछ अलग छाप देगी।


6

यह मेमोरी एड्रेस नहीं है। यह classname @ hashcode है

कहाँ पे

classname = पूर्ण योग्य नाम या पूर्ण नाम (अर्थात पैकेज का नाम जिसके बाद वर्ग नाम)

हैशकोड = हेक्साडेसिमल प्रारूप (System.identityHashCode (obj) या obj.hashCode () आपको दशमलव प्रारूप में हैशकोड देगा)


4

जैसे सुनील ने कहा, यह मेमोरी एड्रेस नहीं है । यह सिर्फ हैशकोड है

समान @ सामग्री प्राप्त करने के लिए, आप यह कर सकते हैं:

यदि हैशकोड उस कक्षा में ओवरराइड नहीं होता है:

"@" + Integer.toHexString(obj.hashCode())

अगर हैशकोड ओवरराइड हो जाता है, तो आपको मूल मूल्य मिलता है:

"@" + Integer.toHexString(System.identityHashCode(obj)) 

यह अक्सर मेमोरी एड्रेस से भ्रमित होता है क्योंकि यदि आप हैशकोड () को ओवरराइड नहीं करते हैं, तो मेमोरी एड्रेस का उपयोग हैश की गणना के लिए किया जाता है।


1

आप जो प्राप्त कर रहे हैं, वह ऑब्जेक्ट क्लास के स्ट्रींग () पद्धति का परिणाम है, या अधिक सटीक रूप से, पहचान हैशोड () uzay95 के रूप में इंगित किया गया है।

"जब हम नए कीवर्ड के साथ जावा में ऑब्जेक्ट बनाते हैं, तो हमें ओएस से मेमोरी एड्रेस मिल रहा है।"

यह महसूस करना महत्वपूर्ण है कि आप जावा में जो कुछ भी करते हैं वह जावा वर्चुअल मशीन द्वारा नियंत्रित किया जाता है। यह जानकारी देने वाला जेवीएम है। होस्ट ऑपरेटिंग सिस्टम की रैम में वास्तव में क्या होता है यह पूरी तरह से JRE के कार्यान्वयन पर निर्भर करता है।



0

जावा में जब आप किसी वर्ग से एक वस्तु बना रहे होते हैं Person p = new Person();, pतो वास्तव में एक मेमोरी लोकेशन का पता होता है जो एक प्रकार की ओर इशारा करता है Person

जब प्रिंट करने के लिए एक स्टेटमेनट का उपयोग करें pतो आपको एक पता दिखाई देगा। newकुंजी शब्द एक नया स्मृति स्थान सभी उदाहरण चर और तरीकों, जिसमें शामिल किए गए हैं युक्त बनाता है class Personऔर pकि स्मृति स्थान की ओर इशारा करते संदर्भ चर रहा है।


आपके चित्र में a1 और a2 दो अलग-अलग मेमोरी एड्रेस हैं। दो अलग-अलग मान प्राप्त करने के पीछे क्या कारण है।
पांडुका वसीसिंघ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.