Доступ к локальной переменной в java - PullRequest
0 голосов
/ 18 марта 2020

Java использует стек для хранения локальной переменной.

see the picture of stack of local variables

Итак, как java получить доступ к локальным переменным. Предположим, что я хочу получить доступ к переменной 'b', сначала она будет выдвигать переменные 'd' и 'c' для доступа к ней? Если нет, то как он хранится в стеке и получает доступ, когда программист должен получить доступ к локальной переменной?

public class Solution {  
 public static void main(String args[]){  
    int a = 5;
    int b = 8;
    int c = 3;
    int d = c*3;
    System.out.println("Testing c "+c);
    System.out.println("Testing b "+b);
    System.out.println("Testing d "+d);
 }
}

1 Ответ

0 голосов
/ 18 марта 2020

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 и посмотрите!

...