代码之家  ›  专栏  ›  技术社区  ›  uzay95

Java中变量的内存地址

  •  122
  • uzay95  · 技术社区  · 15 年前

    请看下图。 当我们在Java中用new关键字创建一个对象时,我们从操作系统.< /p>得到一个内存地址。

    当我们写入 out.println(objname) we can see a“special”string as output.我的问题是:

    1. 这个输出是什么?
    2. 如果是OS给我们的内存地址:

      a)如何将此字符串转换为二进制?

      b)如何获得一个整数变量地址?

      1. . out.println(objName) 我们可以看到一个“特殊”字符串作为输出。我的问题是:

        1. 这个输出是什么?
        2. 如果是OS给我们的内存地址:

          a)如何将此字符串转换为二进制?

          b)如何获得一个整数变量地址?

    8 回复  |  直到 7 年前
        1
  •  141
  •   Socowi    7 年前

    这是类名和 System.identityHashCode() 由“@”字符分隔。标识哈希代码表示的是特定于实现的。它通常是对象的初始内存地址,但是对象可以随着时间的推移在内存中移动。所以(简而言之)你不能指望它是什么。

    在Java中获取变量的内存地址是毫无意义的,因为JVM可以自由地实现对象并按其适合的方式移动它们(您的对象可以在垃圾收集等期间移动)。

    Integer.toBinaryString() 将给出二进制形式的整数。

        2
  •  27
  •   Community noseratio    7 年前

    可以使用 sun.misc.Unsafe :请看@peter lawrey提供的这个很好的答案-> Is there a way to get a reference address?

    将其代码用于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
    

    结论:

    • 哈希代码!=地址
    • toString=class@hex(哈希代码)
        3
  •  11
  •   Paul Tomblin    15 年前

    这是对象的“toString()”实现的输出。如果类重写toString(),它将打印完全不同的内容。

        4
  •  5
  •   Sunil Kumar Sahoo    11 年前

    这是 不是内存地址 这是 classname@哈希码

    在哪里?

    class name=完全限定名或绝对名(即包名后跟类名)

    hashcode=十六进制格式(system.identityhashcode(obj)或obj.hashcode()将提供十进制格式的hashcode)

        5
  •  2
  •   Topera    8 年前

    就像Sunil说的,这不是 内存地址 这只是 哈希码

    要获得相同的@content,您可以:

    如果该类中没有重写哈希代码:

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

    如果hashcode被重写,则使用以下值获取原始值:

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

    这经常与内存地址混淆,因为如果不重写hashcode(),内存地址将用于计算哈希。

        6
  •  1
  •   James P. PachinSV    15 年前

    您得到的是对象类的toString()方法的结果,或者更准确地说,是Uzay95指出的IdentityHashCode()。

    “当我们用Java创建一个新的对象时,我们从OS中得到一个内存地址。”

    认识到Java中所做的一切都是由Java虚拟机处理的,这一点很重要。正是JVM提供了这些信息。在主机操作系统的RAM中实际发生的事情完全取决于JRE的实现。

        7
  •  1
  •   Leon Adler DumDumDummy    9 年前

    在爪哇,当你从类中制造对象时 Person p = new Person(); , p 实际上是指向 Person .

    使用Statemenet打印时 你会看到一个地址。这个 new 关键字生成一个新的内存位置,其中包含 class Person 是指向该内存位置的引用变量。

        8
  •  0
  •   himnabil    9 年前