Общий вопрос: Java имеет кучу и локальный стек. Вы можете получить доступ к любому объекту из кучи?

Я действительно смотрел на различия между передачей по значению и тем, как Java выделяет объекты и что java делает для размещения объектов в стеке.

Есть ли вообще доступ к объектам, выделенным в куче? Какие механизмы обеспечивают java, чтобы гарантировать, что правильный метод может получить доступ к нужным данным из кучи?

Кажется, что если вы были хитрыми и, возможно, даже манипулировали байт-кодом java во время выполнения, вы могли бы манипулировать данными с кучи, когда вы не должны?

Ответы

Ответ 1

В наборе команд JVM нет инструкции, которая дает произвольный доступ к куче. Следовательно, манипуляция с байт-кодом не поможет вам здесь.

JVM также имеет верификатор. Он проверяет код каждого метода (как класс загружается), чтобы убедиться, что этот метод не пытается вытащить больше значений из стека выполнения, чем то, что оно натолкнуло на него. Это гарантирует, что метод не может "видеть" объекты, указанные его вызывающим методом.

Наконец, локальные переменные хранятся в массиве для каждого метода (известный как "массив локальных переменных" ). Опять же, верификатор гарантирует, что каждая команда чтения/записи from-/to- этого массива указывает индекс, который меньше размера массива. Обратите внимание, что эти инструкции JVM могут указывать только постоянный индекс. Они не могут принимать вычисленное значение и использовать его в качестве индекса.

Итак, чтобы ответить, ответ No.

Ответ 2

Все объекты в Java расположены в куче. Я не совсем понимаю, что вы подразумеваете под "доступом к объектам из кучи". Единственное, что хранится в стеке, это список функций, которые вызываются в текущий контекст и их локальные переменные и параметры. Все локальные переменные и параметры являются либо примитивными типами, либо ссылками.

Если вы выделяете объект с помощью new (который является единственным способом выделения не-примитивных типов, да, это включает типы массивов), тогда объект выделяется в куче, а ссылка на этот объект сохраняется на либо стек, либо кучу, в зависимости от того, хранится ли ссылка в локальной переменной/параметре или как член другого объекта.

При передаче в качестве параметров функций все объекты передаются по ссылке - если функция изменяет параметр, исходный объект также изменяется. Точно так же можно было бы сказать, что ссылки на объекты передаются по значению - если вы изменяете параметр для ссылки на новый объект, он будет продолжать ссылаться на этот объект на время действия функции, но исходный объект, который был передан в будет по-прежнему ссылаться на все, о чем говорилось ранее. Примитивные типы также передаются по значению.

Ответ 3

Что касается объектов в стеке, то только новая виртуальная машина Java 6 из SUN (и, возможно, некоторые другие) попытается оптимизировать байтовый код, поместив объекты в стек. Как правило, все объекты попадают в кучу. Для справки: 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 могут привести к изменению вашего пробега.