如果我是正确的,本地定义的原始数据类型将在堆栈上。但是,如果原始数据类型被定义为on对象实例的一部分,则该原语将在堆上进行。
class Test
{
int y=10; // defined as part of the class
public void function1(){
int x = 5; // defined locally
}
public static void main(String[] args)
{
Test obj = new Test();
}
}
所以在上面的代码中,x会被存储在堆栈上吗?y在堆上?我很困惑它们是如何存储的,为什么它与堆栈或堆有关?
答案 0 :(得分:40)
调用方法时,会将某些数据放在堆栈中。方法完成后,将从堆栈中删除数据。在程序执行的其他时刻,数据被添加到堆栈中,或从中删除。
因此,如果您的变量旨在比创建它的方法的执行寿命更长,那么它需要在堆上。这适用于您创建的任何对象以及存储在这些对象中的任何基元。
但是,如果变量在创建后不久就要超出范围 - 比如,在创建它的方法的最后,或者甚至更早,那么它适合于要在堆栈上创建的变量。局部变量和方法参数符合这个标准;如果它们是基元,则实际值将在堆栈上,如果它们是对象,则对象(但不是对象本身)的引用将在堆栈上。
在您的具体示例中,只要x
完成运行,function1
就无法使用。因此,在堆栈上创建它是合理的。在function1
结束时,数据会从堆栈中有效删除,包括x
。另一方面,只要包含对象存在,变量y
预计仍然存在;如果它是在堆栈上创建的,一旦创建它的对象构造函数完成运行,它就会停止存在。因此,必须在堆上创建y
。
答案 1 :(得分:18)
只有本地原始变量和对象的引用(即方法中声明的变量)存储在堆栈中。其他的存储在堆
中答案 2 :(得分:4)
我很确定你现在得到了答案......有一点需要注意。即使您将变量存储在堆上,Java仍然会在需要对其进行操作时将其值加载到堆栈上。这就是JVM的工作方式 - 它是一种堆栈语言。
答案 3 :(得分:2)
实例级别变量(也可以是基元)是实例(对象)的一部分。因此,它们将在堆上分配(作为对象的一部分。)
方法级别/局部变量:堆栈(用于基元)或堆栈(在堆栈上具有引用的对象)。字符串可以在Stack或堆上分配。
答案 4 :(得分:0)
当您发起Test
个实例时,其所有字段(如y
)都将存储在堆中。
当您致电function1
时,本地可变x
将被推入筹码。
但在您的示例中,x
未存储在堆栈中,因为永远不会调用function1
。