方法本地类?

时间:2012-08-27 00:00:25

标签: java

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

亲切的问候。

1 个答案:

答案 0 :(得分:1)

  

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

您的术语不正确,这可能是您混淆的根源:

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

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

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

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

  

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

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


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

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