2017-04-17 235 views
0

我的网站上(http://www.rajeshpatkar.com/articles/javarefpnt/),该读出时,我们实例化一个类即Java中的句柄的概念是什么?

Emp e = new Emp(); 

甲句柄存储在变量e,即它不对象的地址存储在存储器中,其不是指针。

该解释给出了一个指针数组的例子。存储器地址存储在[1]位置,当对象移动时,该位置用新地址更新。

那么为什么这个数组被用来代替直接存储地址(它声明它有助于GC,但我不理解它)并在对象移动时更新它(存储在e中的地址)?

我花了相当多的时间来理解这一点,但仍然没有找到满足我的答案。 所以,如果你能解释一下实际存储在变量'e'中的东西(举一个例子),它会很有帮助。

谢谢:)

回答

5

通常的术语是“对象引用”(或只是“参考”),而不是“处理”。

对象引用是一个不透明的值,它向JVM唯一标识某个对象。该值的形式不是由规范以外的规定。我怀疑它的尺寸通常是intlong,但我认为即使这个尺寸不在JLSJVM规范中。 (为了给你一个想法,JVM规范明确指出,即使确切的值为null [特殊值的含义是“no reference”]不是强制性的。)

引用不是指针,虽然当然自从没有指定引用的形式,只要不违反规范就可以利用指针作为引用来实现JVM。

因为引用不是指针,所以Java没有像C和其相关语言那样的“指针算术”。

所以,如果你能解释一下实际存储在变量'e'中的内容(举例),这将很安静。

它没有被规范定义。它只是一个唯一标识对象的值(我们永远无法看到该值;当您使用System.out来打印未实现toString的对象时,看到的十六进制值是对象的引用的神话就是:神话)。 该值如何标识该对象是由JVM的实现决定的。它可能是一个指针。它可能是一个指针数组的索引。它可能更复杂,使用参考值中的不同位来表示不同的事情。

+0

很好的解释队友。我终于理解了句柄的概念。继续使用指针数组的例子,即'e'(引用变量)指向一个[1](依次[1])存储对象的地址。另外我知道我们不能改变'e'的值,也就是说我们不能在e中指向[5]或java中的任何其他内存,只有内容即存储在[1]中的值可以改变。这在Java中的原因是什么,即为什么不允许将'e'指向java中的任何其他位置?允许它有什么风险? –

+2

@JayeshSaita:很高兴帮助。 *“...我进一步知道我们不能改变'e'的值......”是的,我们可以:'e = someOtherObject;'不要被JVM如何实现它。只是:变量存储值。存储在引用类型变量中的值是一个对象引用。该值告诉JVM对象在哪里。 :-) –

1

句柄存储在变量e中,该变量不是指针,即 不存储对象在内存中的地址。

出于所有实际目的,您可以假定它将对象的地址存储在内存中。

但是,在Java中考虑不能以明确的方式管理内存。这意味着你不能让这种变量指向内存中的特定位置。你可以将这个变量指向特定的实例。

+0

*“为了所有实际目的......”* - 除了压缩的oops之外 - http://stackoverflow.com/questions/25120546/trick-behind-jvms-compressed-oops –

+0

确实,在64 bit JVM – Andres

+0

我想,并非所有的实际目的。有hashcode()通常通过将对象引用转换为整数来实现(尽管这不是必需的),对吧?相反,如果它依赖于内存中的指针,那么即使对象没有变异,此实例的每个GC移动都会使其返回不同的哈希码。这违反了hashcode()的合同。 –