比如我有两个类,分别是TestA 和 TestB
public class TestA {
public List<String> list = new ArrayList<String>();
}
public class TestB {
public static void main(String[] args) {
TestA a = new TestA();
a.list.add("Test");
}
}
我看书的时候说所有的reference都保存在栈中,而new出来的对象属性 包括全局属性都保存在堆中, 那么a应该是保存在栈里面,而new出来的TestA中的list这个Reference保存在堆还是栈啊,很困惑。
希望各位大侠解惑,谢谢
static变量的引用在方法区,方法区可以位于堆上也可以位于栈上
非static变量的引用都在java堆上,跟对象是一起的
只有方法调用的时候,才会有java栈的操作,才会将引用入栈、出栈,但这也只是临时的,方法调用结束后,栈帧就废弃了
所以,在main方法中,本身是一个方法调用,java栈有main方法的帧,new出来的TestA中的list对象本身在堆上,引用也在堆上,但.add操作的时候会将堆中list的引用入栈以完成add操作
栈中。虽然new出来的对象在堆中,但是不代表里面的都在堆中,底层里面有自己的映射的。
[code="java"] public List list = new ArrayList(); [/code]
这个list在栈中,new ArrayList()在堆中,引用list指向堆中new 的ArrayList
[code="java"] TestA a = new TestA(); [/code]
a也在栈中,new TestA()在堆中,引用a指向堆中new的 TestA(),注意这个引用a指向的是TestA的对象
[code="java"] a.list.add("Test"); [/code]
调用对象a的成员变量list的add方法,传入字符串参数"Test"
综上,a list都是在栈中,只是指向不同而已
其实很简单,就是对象或者方法名就是一个个的映射在栈中,而他们的实体放在堆中通过一个个的映射关系可以取得
如果楼主对这个问题很感兴趣,那么只有深入理解的jvm的工作原理才能理解的更透彻
我觉得lz看下《深入java虚拟机》第二版后对这个问题就大彻大悟了