在Java中,null如何在内存中表示。

6

可能是重复内容:
Java中null在内存中到底是什么

有人知道在对象或其他情况下,如何在内存中表示空值吗?在dot net中,它由空指示器布尔值和相应类型的值表示(参见此处)。那么有人知道在Java中是如何实现的吗?


2
你所提到的问题有些误导人,被接受的答案完全是关于Nullable<T>而不是空引用 - Jon Skeet
请查看此问题的被接受答案,它将帮助您理解 Java 中的 null。https://dev59.com/anE85IYBdhLWcg3wkkjK - Abin Manathoor Devasia
4个回答

9
根据JVM规范第2.4节,Java虚拟机规范并没有规定空值的具体编码。因此它可以是任何值,但很可能是一个引用值,其所有位都为零。引用本身可以是简单指针(即仅是虚拟地址,与本机指针一样,大小适合于该架构),但也不必如此。一些JVM具有非常智能的引用处理方式 - 例如,Hotspot可以在许多情况下使用32位值作为引用,即使在x64进程中运行也是如此。

Java虚拟机规范没有规定一个具体值来编码null。在这种情况下,它如何进行(反)序列化? - fge
2
@fge:那是内存中的表示,与序列化完全独立。 - Jon Skeet

2

理论上,它是JVM的一个秘密,在32位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

这只是证明当尝试将空引用作为int读取时,“Unsafe”(最终)返回零。还要考虑getInt文档中的一段话:“但是,如果该变量实际上不是此方法返回的类型,则结果是未定义的...” - user85421

1

确切的表示方式未指定,但我认为它只是像其他类C语言一样的0x0。这是一个特殊的值,否则不会出现,不是额外的字段或额外的信息。

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

顺便说一下:大多数64位JVM使用32位引用,除非堆大小为32 GB或更大。这在OpenJDK JVM中是可能的,因为所有对象都是8字节(或16字节)对齐的。由于较低的3或4位始终为0,它们不需要被存储,将地址范围扩展了8倍或16倍的典型4 GB范围。


@HannesHertach,我已经解释了为什么32位引用可以寻址32 GB的内存。 - Peter Lawrey

1

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

当您执行以下操作时:

String str = null;

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


你的概念中参考是什么?只是抽象数字吗? - Andremoniy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接