构造函数调用是否也进入堆栈?

Does constructor call also go on the stack?

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

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() first 的状态是否被推入堆栈(甚至在 initialize() 被推入之前),尽管如此是构造函数而不是方法?

保存构造函数状态和方法状态之间有显着差异吗?

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

归根结底,构造函数就像任何其他方法一样。它接受任何类型的参数和 returns 它自己类型的对象。它像其他任何东西一样放在调用堆栈上,并显示为 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)

从Java语言的角度来看,这是特定于实现的; JLS 并没有过多说明方法是否需要堆栈,或者它必须是什么样子,只是说(在 15.12.4.5 中)如果方法调用不能发生,因为框架不能创建后,它应该抛出 WhosebugException。

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

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

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

  public static void main(String[] args) {
    new ConsBoom();
  }
}