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);
}
}
Java使用堆栈来存储局部变量。
或多或少是不正确的。
字节码形式的Java是堆栈和可访问变量的组合。是的,有一个堆栈,但也有一个小的变量存储系统,而大多数局部变量最终都在该系统中。可以生成字节码,以将变量放入插槽中,并从插槽中加载变量,而不必先连续地“顶”上弹出和弹出所有内容。
这是一个简单的例子;采取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]有一个常量池。常量池中的“索引”包含例如完整的方法引用(因此,完全合格的类名+方法名+方法的签名)是字节码的一部分,用于诸如“调用此构造函数”,“读取此字段”,等等。javap输出中的#x标记是对此常量池的引用。
对于您的代码段,我邀请您执行与我相同的操作:将其编写在一个非常简单的java文件中,进行编译,然后运行javap -c -private MyClass
并看一下!