有没有人知道如何在内存中为对象或任何东西表示null值。在dot net中,它由空指示符布尔值和相应类型的值(Refer here)表示。那么任何人都知道如何在java中完成它吗?
答案 0 :(得分:9)
来自JVM specification, section 2.4:
Java虚拟机规范没有强制要求编码null的具体值。
所以可能可以是任何东西,但它很可能是一个全零的参考值。引用本身可以是简单的指针(即,只是一个虚拟地址,与本机指针一样,具有适当的体系结构大小),但同样不必如此。有些JVM有非常智能的方法来处理引用 - 例如,Hotspot是able to use 32-bit values for references in many situations, even when running in an x64 process。
答案 1 :(得分:2)
理论上它是JVM的秘密,实际上它在32-bin VM上是0(0x00000000)。如果使用Oracle JVM,则可以使用sun.misc.Unsafe(可以读取任何地址的内存内容)进行验证。
public class Test {
int i1 = 100;
String s = null;
int i2 = 200;
public static void main(String[] args) throws Exception {
Test test = new Test();
System.out.println(getInt(test, "i1"));
System.out.println(getInt(test, "s"));
System.out.println(getInt(test, "i2"));
}
static int getInt(Test test, String name) throws Exception {
Unsafe u = getUnsafe();
long offset = u.objectFieldOffset(Test.class.getDeclaredField(name));
return u.getInt(test, offset);
}
static Unsafe getUnsafe() throws Exception {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
}
}
输出
100
0
200
答案 2 :(得分:1)
没有指定确切的表示,但我认为它只是0x0
,就像在其他C语言上一样。这是一个特殊的价值,不能以其他方式发生,不是额外的领域或额外的信息。
注意:当您拥有String
时,它是引用而不是对象。这个4字节的值可以引用一个对象,或者在null
的情况下是一个不是有效对象的值。
BTW:大多数64位JVM使用32位引用,除非堆是32 GB或更多。这在OpenJDK JVM中是可能的,因为所有对象都是8字节(或16字节)对齐。由于低3位或4位始终为0,因此无需存储,将地址范围扩展8倍或典型4 GB范围的16倍。
答案 3 :(得分:1)
不应为null本身分配内存,因为null实际上不是有效的对象实例。它只是一个占位符,表示对象引用当前不是指对象。
当您执行以下操作时:
String str = null;
唯一分配的是对字符串的引用(这类似于包含指针类型的语言中的字符串指针)。此引用是一个32位或64位变量(取决于您的硬件架构和Java版本),它位于堆栈中(可能取决于您的声明所在的确切上下文)。