作为程序员,我认为这些看起来像是"位于地址1a234552的java.lang.Object"或类似于s
在中的某些内容。
Object s = "hello";
这是否正确?因此,所有引用都是固定大小的吗?
作为程序员,我认为这些看起来像是"位于地址1a234552的java.lang.Object"或类似于s
在中的某些内容。
Object s = "hello";
这是否正确?因此,所有引用都是固定大小的吗?
虽然在许多虚拟机上,引用的大小是本地指针大小(即32位JVM的32位和64位JVM的64位),但这并不是保证 - 特别是HotSpot现在或不久将支持"Compressed Oops",它们是64位JVM中的32位引用。(这并不意味着每个引用都被压缩了 - 阅读链接的文章以获取更多信息,并且还有很多博客文章可供参考。)
针对另一个评论,需要注意的是,引用本身通常只是寻址对象本身的一种方式。无论它是直接内存指针还是其他类型,其目标都是获取对象的数据。这基本上是所有真正重要的事情。如果有一些“备用”位(例如它是64位引用,您不需要所有宽度来表示对象的位置),则VM可以使用该数据进行其他信息,例如其类型,这可能允许一些优化。(有关详细信息,请参见Tom的评论。)
对象本身包含类型信息(可能以Class
实例的引用形式或类似形式存在 - 我不太清楚),以及头部中必要的其他“东西”,然后才能到达对象的用户数据。
这不属于JLS或JVM规范,但实际上它将是一个地址:32位CPU上为32位,64位CPU上为64位。
pqism: 好的,我明白了,因为在编译后,我们不再关心声明的类型了?
我们确实关心。这就是为什么存在Class对象的原因。事实上,从其他答案中可以看出,我们足够关心类型以至于通过将类型信息的一部分放入引用中来优化与其交互的方式。
Object[10000]
,就像 Map 的支撑数组一样。你实际上不知道是否会使用所有这些条目,而且由于负载因子,它们几乎肯定不会被使用。在这种情况下,在数组序列中存储类型信息是极其愚蠢的。最好将类型信息放在各个对象本身上。 - Sune Rasmussen大多数人倾向于将对象引用视为类似于C语言内存指针的东西。虽然这在技术上并不正确,但大多数实现确实将其实现为指针。例如,在使用压缩对象指针的情况下,JVM仅在64位平台上存储64位指针的3到34位。其他实现也可以选择使用不同的方案:引用可以是包含所有对象的指针数组中的索引。
JLS
,而是JVMS
,但除此之外 - 是的,规范并没有禁止这样做。 - Eugene