3

我知道在 Java 中所有方法调用都在堆栈上。以下面的类为例:

Class Demo
{
   // Some instance variables
   public Demo()
   {
      initialize();
   }

   public void initialize()
   {
      // Start initialization
      ....

      // Call another method to perform some complex calculation
      int resultVal = helperMethod();

      // Perform the remaining initialization work

   }


   public int helperMethod()
   {
      // Perform some complex calculation 
      ....

      return result;
   }

}

首先initialize()(及其状态)被压入堆栈,然后当它调用时 helperMethod(),状态helperMethod()也被压入堆栈。

但是我想了解的是,尽管它是构造函数而不是方法,但状态是否Demo() 首先被推入堆栈(甚至在被推入之前)?initialize()

保存构造函数状态和方法状态之间是否存在显着差异?

4

3 回答 3

2

当它真正归结为它时,构造函数就像任何其他方法一样。它接受任何类型的参数并返回它自己类型的对象。它像其他任何东西一样放在调用堆栈上,并显示为Demo.<init>()

您的示例调用堆栈跟踪中的异常看起来像

Exception in thread "main" java.lang.NullPointerException
    at Demo.helperMethod(Demo.java:30)
    at Demo.initialize(Demo.java:16)
    at Demo.<init>(Demo.java:7)           <---------
    at Demo.main(Demo.java:36)
于 2015-07-24T21:24:27.470 回答
2

从 Java语言的角度来看,这是特定于实现的;JLS 没有过多说明方法是否甚至需要堆栈,或者它必须是什么样子,只是说(在15.12.4.5中)如果由于无法创建框架而无法进行方法调用,它应该抛出一个 StackOverflowException。

从 Java平台的角度来看(即由兼容的 JVM 执行的语言),构造函数方法,因此就堆栈帧而言,其功能相同。JVMS 2.9将构造函数描述为“特殊方法”,但就堆栈框架而言,它并没有改变它们的任何内容。

您可能知道,当您调用太多方法而没有从它们返回时,就会发生堆栈溢出异常;在实践中,当你有无限递归时,这是最常见的。如果每个对象总是构造它自己的另一个实例(即构造的无限递归),那么构造函数可能会导致同样的问题。

public class ConsBoom {
  public ConsBoom() {
    new ConsBoom();
  }

  public static void main(String[] args) {
    new ConsBoom();
  }
}
于 2015-07-24T21:24:54.813 回答
1

是的。对构造函数的调用就像常规方法一样使用堆栈。

于 2015-07-24T21:15:04.680 回答