一般问题:Java有堆和本地堆栈。你能访问堆中的任何对象吗?

问题描述:

我真的在研究按值传递和Java如何分配对象以及java如何将对象放在堆栈上的差异。一般问题:Java有堆和本地堆栈。你能访问堆中的任何对象吗?

有无论如何访问分配在堆上的对象吗? java执行什么机制来保证正确的方法可以从堆中访问正​​确的数据?

看起来好像如果你很狡猾,甚至可能在运行时操纵java字节码,那么当你不应该这样做时,你可能能够从堆中操纵数据?

+1

好问题 - 我希望我更了解java;一个很好的答案将是我的启示:) – 2008-11-14 03:33:21

JVM指令集中没有任何指令允许任意访问堆。因此,字节码操作在这里不会帮助你。

JVM还有一个验证器。它检查每个方法的代码(作为一个类正在被加载),以验证该方法不会尝试从执行堆栈中弹出更多的值,而不是将其推送到其上。这确保方法不能“看到”其调用方法所指向的对象。

最后,局部变量存储在每个方法数组(称为“局部变量数组”)中。同样,验证器确保来自该数组的每条读/写指令都指定一个小于数组大小的索引。请注意,这些JVM指令只能指定一个常量索引。他们无法获得计算值并将其用作索引。

因此,要回顾一下,答案是

+0

我刚刚回到这个。所以基本上Java的结构和类似的垃圾收集,基于堆栈的语言是这样的,当你没有权限的时候,你不能任意访问堆的一部分。 – 2011-08-16 03:00:58

Java中的所有对象都位于堆上。我不太清楚“从堆中访问对象”的含义。存储在堆栈中的唯一东西是调用到当前上下文中的函数列表及其局部变量和参数。所有本地变量和参数都是原始类型或引用。

如果您使用new(这是分配非基元类型的唯一方式;这包括数组类型)分配对象,则该对象将分配在堆上,并且该对象的引用将存储在堆栈或堆,取决于引用存储在局部变量/参数中还是作为另一个对象的成员。

当作为参数传递给函数时,所有对象都通过引用传递 - 如果函数修改参数,原始对象也会被修改。同样,也可以说对象引用是按值传递的 - 如果你改变一个参数来引用一个新对象,它将继续在该函数的持续时间内引用该对象,但是传入的原始对象仍然会参考之前提到的任何内容。原始类型也通过值传递。

+0

还有其他的方式来分配新的对象(克隆,Class.newInstance(),反序列化),但他们都是最终堆在堆上。 – 2008-11-14 05:03:49

+4

“人们也可以说对象引用是按值传递的”解释是唯一准确的。说对象通过引用传递是不准确的。基本上Java只有传递值,就像C. – 2008-11-14 07:11:44

关于堆栈上的对象号,它只是从SUN新的Java 6 VM(也许还有一些其他)将尝试通过将对象优化字节码堆栈。通常情况下,所有对象都将进入堆中。仅供参考,请查看:http://www.ibm.com/developerworks/java/library/j-jtp09275.html

此外,JVM规格为http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348。 JVM通过简单地不给你需要的指示来保护它的堆。 JVM实现中的缺陷可能会导致您的里程数发生变化。