-4

当我们在函数中声明一个类并创建该类的变量时,该类的对象是推入堆栈还是堆?在内部类的上下文中使用 final 关键字时,我有些困惑?如果变量和类对象都存在于堆栈中,为什么我们需要将变量命名为 final ?

亲切的问候。

4

1 回答 1

1

当我们在函数中声明一个类并创建该类的变量时,该类的对象是压入堆栈还是堆?

您的术语不正确,这可能是您困惑的根源:

  • 类的声明不会导致分配任何空间……除了在加载和初始化类时用于表示代码、静态等的空间的一次性分配。

  • Java 有方法,而不是函数。

  • 当您在方法中声明变量(即局部变量)时,变量本身的空间会在堆栈上分配。(如果您声明一个静态或实例变量,该空间将成为堆节点的一部分。)

  • 当您创建类的实例(即对象)时,该实例的空间在堆1上分配。该实例的引用可以分配给堆栈(用于方法中的局部变量)或堆(用于静态或实例变量)上的先前分配的变量...但也可以立即丢弃。无论哪种方式,用于引用的空间分配都与实例的创建无关。

在内部类的上下文中使用 final 关键字时,我有些困惑?如果变量和类对象都存在于堆栈中,为什么我们需要将变量命名为 final ?

是必需的final,因为 Java 不支持正确的闭包。当内部类引用封闭范围内的局部变量时,会发生什么情况是变量的值被传递给内部类并存储在隐藏变量中。允许编译器有效地对final应用程序隐藏它。由于应用程序无法更改变量的内容,因此无法判断变量2有两个副本。


1 - 这有点过于简单化了。如果您有兴趣,请阅读“逃逸分析”。

2 - 这是局部变量存储在堆栈上的规则的例外。在这种情况下,变量的副本存储在内部类实例的堆节点中。然而,这是一个实现细节......就像所有堆栈与堆的东西一样。如果 JVM 架构被更改为支持闭包,事情可能会有所不同。

于 2012-08-27T01:16:52.217 回答