我知道在Java(也许在.net中),原始类型存储在堆栈上,而引用类型存储在堆上。我的问题是,我不理解这种行为的优缺点。为什么我们不能引用堆栈内部的内存位置呢?我在谷歌上搜索了一下,但没有找到合适的解释(也许是我不擅长),如果你们能提供一些见解,我将不胜感激。谢谢。
String someMethod() {
int i = 0;
String result = "Hello";
i = i + 5;
return result;
}
int i
)被创建在栈上,并对其进行了一些计算。一旦方法完成,就无法再访问i
,它的值也会丢失。对于result
引用,基本上也是如此:引用被分配在堆栈上,但对象(在本例中为字符串对象)则被分配在堆上。通过将引用作为返回值返回,它所引用的对象仍然可以在方法外部使用。一般情况下,你不能将引用类型存储在栈上,因为栈帧在方法返回时被销毁。如果你保存了一个对象的引用,以便在方法完成后可以取消引用它,那么你将会取消引用一个不存在的栈位置。
HotSpot JVM 可以执行逃逸分析,如果它确定一个对象不可能逃出方法范围,它实际上会在栈上分配该对象。
Abc
对象所占用的空间和指向Abc
对象的引用(指针)所占用的空间。在Abc obj = new Abc()
中,内存被分配到堆上用于存储Abc
对象,并且(假设代码行是方法体的一部分)为obj
引用分配了栈上的空间。 - Andreas Fester与之相反,引用类型存储在堆上。
我不知道您所说的部分具体指什么,但请记住,只有对象存储在堆上,而指向这些对象的引用仍然存储在栈上。可能这就是您的疑惑所在。
现在,您还应该注意,只有局部变量存储在栈上,而实例/成员变量存储在堆上。
例如:-
String str = new String("Rohit"); // Local variable
str
在某个本地作用域中定义,则该引用将在stack
上分配内存,并且它将指向在Heap
上创建的新字符串对象。