Java中变量的内存地址
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1961146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Memory address of variables in Java
提问by uzay95
Please take a look at the picture below.
When we create an object in java with the new
keyword, we are getting a memory address from the OS.
请看下面的图片。当我们使用new
关键字在 java 中创建对象时,我们从操作系统获取内存地址。
When we write out.println(objName)
we can see a "special" string as output. My questions are:
当我们编写时,out.println(objName)
我们可以看到一个“特殊”字符串作为输出。我的问题是:
- What is this output?
If it is memory address which given by OS to us:
a) How can I convert this string to binary?
b) How can I get one integer variables address?
- 这是什么输出?
如果是操作系统给我们的内存地址:
a) 如何将此字符串转换为二进制?
b) 我怎样才能得到一个整数变量地址?
采纳答案by Brian Agnew
That is the class name and System.identityHashCode()separated by the '@' character. What the identity hash code represents is implementation-specific. It often is the initial memory address of the object, but the object can be moved in memory by the VM over time. So (briefly) you can't rely on it being anything.
即类名和System.identityHashCode()以“@”字符分隔。身份哈希码所代表的内容是特定于实现的。它通常是对象的初始内存地址,但随着时间的推移,VM 可以将对象移动到内存中。所以(简而言之)你不能依赖它是任何东西。
Getting the memory addresses of variables is meaningless within Java, since the JVM is at liberty to implement objects and move them as it seems fit (your objects may/will move around during garbage collection etc.)
在 Java 中获取变量的内存地址是没有意义的,因为 JVM 可以自由地实现对象并根据需要移动它们(您的对象可能/将在垃圾收集期间移动等)
Integer.toBinaryString()will give you an integer in binary form.
Integer.toBinaryString()会给你一个二进制形式的整数。
回答by Paul Tomblin
That is the output of Object's "toString()" implementation. If your class overrides toString(), it will print something entirely different.
那是 Object 的“toString()”实现的输出。如果您的类覆盖 toString(),它将打印完全不同的内容。
回答by James P.
What you are getting is the result of the toString() method of the Object class or, more precisely, the identityHashCode() as uzay95 has pointed out.
您得到的是 Object 类的 toString() 方法的结果,或者更准确地说,是 uzay95 指出的 identityHashCode() 。
"When we create an object in java with new keyword, we are getting a memory address from the OS."
“当我们用 new 关键字在 java 中创建一个对象时,我们从操作系统获取了一个内存地址。”
It is important to realize that everything you do in Java is handled by the Java Virtual Machine. It is the JVM that is giving this information. What actually happens in the RAM of the host operating system depends entirely on the implementation of the JRE.
重要的是要意识到您在 Java 中所做的一切都是由 Java 虚拟机处理的。提供此信息的是JVM。主机操作系统的 RAM 中实际发生的情况完全取决于 JRE 的实现。
回答by Sunil Kumar Sahoo
This is not memory addressThis is classname@hashcode
这不是内存地址这是classname@hashcode
where
在哪里
classname = full qualified name or absolute name (ie package name followed by class name)
classname = 完全限定名称或绝对名称(即包名后跟类名)
hashcode = hexadecimal format (System.identityHashCode(obj) or obj.hashCode() will give you hashcode in decimal format)
hashcode = 十六进制格式(System.identityHashCode(obj) 或 obj.hashCode() 会给你十进制格式的 hashcode)
回答by JBE
It is possible using sun.misc.Unsafe
: see this great answer from @Peter Lawrey -> Is there a way to get a reference address?
可以使用sun.misc.Unsafe
:从@Peter Lawrey 看到这个很棒的答案->有没有办法获得参考地址?
Using its code for printAddresses() :
将其代码用于 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();
}
I set up this test :
我设置了这个测试:
//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);
Here is the output :
这是输出:
Hashcode : 125665513
Hashcode : 125665513
Hashcode (HEX) : 77d80e9
toString : java.lang.Object@77d80e9
Address: 0x7aae62270
Conclusion :
结论 :
- hashcode != address
- toString = class@HEX(hashcode)
- 哈希码 != 地址
- toString = class@HEX(hashcode)
回答by himnabil
this is useful to know about hashcode in java :
这对于了解 java 中的哈希码很有用:
http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/
http://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/
回答by Panduka Wedisinghe
In Java when you are making an object from a class like Person p = new Person();
, p
is actually an address of a memory location which is pointing to a type of Person
.
在 Java 中,当您从类创建对象时Person p = new Person();
,p
实际上是指向Person
.
When use a statemenet to print p
you will see an address. The new
key word makes a new memory location containing all the instance variables and methods which are included in class Person
and p
is the reference variable pointing to that memory location.
使用statemenet 打印时,p
您将看到一个地址。的new
键字,使包含所有这些都包括在实例变量和方法的新的存储位置class Person
和p
所指向的存储器位置的参考变量。
回答by Topera
Like Sunil said, this is not memory address.This is just the hashcode
就像 Sunil 说的,这不是内存地址。这只是哈希码
To get the same @ content, you can:
要获得相同的@内容,您可以:
If hashCode is not overridden in that class:
如果该类中未覆盖 hashCode:
"@" + Integer.toHexString(obj.hashCode())
If hashCode is overridden, you get the original value with:
如果 hashCode 被覆盖,您将获得原始值:
"@" + Integer.toHexString(System.identityHashCode(obj))
This is often confused with memory address because if you don't override hashCode(), the memory address is used to calculate the hash.
这经常与内存地址混淆,因为如果您不覆盖 hashCode(),内存地址将用于计算散列。