如何在java的内存中表示null

可能重复:
Java内存中究竟是什么null

有没有人知道如何在对象或任何东西的内存中表示空值。 在dot net中,它由空指示符布尔值和相应类型的值表示( 请参阅此处 )。 所以有谁知道它是如何在java中完成的?

从JVM规范,第2.4节 :

Java虚拟机规范并未强制要求编码null的具体值。

所以它可能是任何东西,但它很可能是一个全零的参考值。 引用本身可以是简单的指针(即,只是一个虚拟地址,与本机指针一样,具有适当的体系结构大小),但同样不必如此。 一些JVM具有处理引用的非常智能的方法 – 例如, 在许多情况下,即使在x64进程中运行 ,Hotspot也能够在引用中使用32位值 。

不应为null本身分配内存,因为null实际上不是有效的对象实例。 它只是一个占位符,表示对象引用当前不是指对象。

当你做类似的事情:

String str = null;

分配的唯一东西是对字符串的引用(这类似于包含指针类型的语言中的字符串指针)。 此引用是一个32或64位变量(取决于您的硬件体系结构和Java版本),它位于堆栈中(可能取决于声明所在的确切上下文)。

理论上它是一个JVM秘密,实际上它在32-bin VM上是0(0x00000000)。 如果使用Oracle JVM,则可以使用sun.misc.Unsafe(可以读取任何地址的内存内容)进行validation。

 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 

确切的表示没有指定,但我认为它只是像其他C语言一样的0x0 。 这是一个特殊的值,不能以其他方式发生,不是额外的字段或额外的信息。

注意:当你有一个String它是一个引用而不是一个Object。 这个4字节的值可以引用一个对象,或者在null的情况下是一个不是有效对象的值。

BTW:大多数64位JVM使用32位引用,除非堆是32 GB或更多。 这在OpenJDK JVM中是可能的,因为所有对象都是8字节(或16字节)对齐。 由于低3位或4位始终为0,因此无需存储将地址范围扩展8倍或典型4 GB范围的16倍。