帧(frame)
Java调用函数时会创建一块与被调用函数相对应的内存,作用是存放函数中的局部变量及运行时的其他信息。这块内存就叫做帧(frame)。
栈里的每一个元素是一个frame。
当我们说栈时,可能指一种特定的数据结构,也有可能指程序运行时所使用的这一块内存。
public class Test{
public static void main(String args[]){
int a=1;
int b=2;
fr(a,b);
int t=a+b;
}
public static void fr(int a,int b){
a++;
b++;
return;
}
}
main函数执行时会创建一个frame
main |
---|
… |
a=1 |
b=2 |
… |
当main调用fr函数时,就会创建一个属于fr函数的frame,紧跟在main函数之后
main |
---|
… |
a=1 |
b=2 |
… |
fr |
---|
… |
a=2 |
b=3 |
… |
当fr执行完之后,fr所对应的的frame就会销毁,回到main的frame中进行操作。此时的a还是1,b还是2。因为在main函数调用fr函数时,把main中的a,b做了一次拷贝,把这两个整数复制到了fr的frame里,我们在fr里对传进来的参数进行操作,只能改动fr这个frame里的变量,而不能改变main里面的变量。
main |
---|
… |
a=1 |
b=2 |
f=3 |
… |
栈和堆
在函数调用时,往新的frame中传递参数时会把参数拷贝一份过去,而在被调用函数的frame中对参数进行更改,是不会对调用者的数据产生影响。但这是在参数都是基础类型,如int,double,float等的前提下才成立。对于普通的Java对象则不成立。
堆(heap)是一块独立内存空间。在创建对象时我们把真正的对象放到堆里,在栈(stack)中记录这个对象的地址就可以了。
public class Test {
public static void main(String args[]){
demo a=new demo(1);
demo b=new demo(2);
fr(a,b);
int t=a.value+b.value;
System.out.print(t);
}
public static void fr(demo a,demo b){
a.value++;
b.value++;
}
}
class demo{
public int value;
public demo(int v){
this.value=v;
}
}
在main和fr的栈里都只存了一个指向堆里真实对象的引用(地址),在fr中对a,b的value操作,调用fr结束时,在main中可以看到a,b的value以更改。
stack
Key | Value |
---|---|
a | 2 |
b | 3 |
t | 5 |