Java использует стек для хранения локальной переменной.
Это более или менее неверно.
Java в форме байт-кода представляет собой комбинацию стеков и доступные переменные. Да, есть стек, но есть также небольшая система хранения переменных, и вместо этого большинство локальных переменных попадают в эту систему; может быть сгенерирован байт-код, чтобы поместить переменную в слот и загрузить переменную из слота, не выполняя непрерывную операцию pu sh и сначала выталкивая все «сверху».
Вот тривиальный пример; принять java код:
public static void test() {
Test t = new Test();
System.out.println(t.a + t.b);
}
class Test {
int a, b;
}
превращается в этот байт-код:
meta: stack=3, locals=2 ; [1]
INVOKESPECIAL #9 ; [2] 'new Test() -> result on stack'
stack now: instance of Test
ASTORE_1 ; Pop stack and put result in 'slot 1'
stack now: empty.
GETSTATIC #10 ; Read field 'System.out' -> result on stack.
stack now: Sysout
ALOAD_1 ; Copy 'slot 1' onto stack.
stack now: instance of Test, Sysout.
GETFIELD #16 ; Consume top of stack, read a field, put that on stack.
stack now: int (t.a), Sysout.
ALOAD_1
stack now: instance of Test, t.a, Sysout.
GETFIELD #20
stack now: t.b, t.a, Sysout.
IADD ; this has no params, it's all stack based.
stack now: the sum of t.a+t.b, Sysout.
INVOKEVIRTUAL #23 ; the println method
stack now: empty (the invokevirtual consumed it all).
примечания к вышесказанному:
[1] в байт-коде, самый большой стек будет когда-либо, и большинство из тех «локальных переменных», которые нам когда-либо понадобятся, будет отслежено. Вы можете увидеть это с помощью javap.
[2] Существует постоянный пул. «Индекс» в пул констант, содержащий, например, полную ссылку на метод (таким образом, полное имя класса + имя метода + сигнатура метода) является частью байт-кода для таких вещей, как «вызвать этот конструктор», «прочитать это поле», и др c. Знаки #x в выводе javap являются ссылками на этот постоянный пул.
Для вашего фрагмента я предлагаю вам сделать то же, что и я: записать его в очень простой файл java, скомпилировать его, затем запустите javap -c -private MyClass
и посмотрите!