【问题标题】:Does constructor call also go on the stack?构造函数调用是否也在堆栈上?
【发布时间】:2015-07-24 21:11:32
【问题描述】:

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

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

【问题讨论】:

    标签: java methods constructor stack state-saving


    【解决方案1】:

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

    【讨论】:

    • 构造函数不返回对象。它是新的运算符。
    【解决方案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();
      }
    }
    

    【讨论】:

    • 在 JVMS 中讨论了堆栈和构造函数作为方法的实现:herehere
    • @SotiriosDelimanolis 是的,就 JLS 而言,这是对实现的描述。其中的所有内容都是 Oracle JVM 的实现细节,而不是 Java 语言的任何实现的要求。
    • JVMS,Java 虚拟机规范,是所有 JVM 的规范。
    • 我想这取决于您是否将“Java”视为语言或平台;我通常认为它只是一种语言,平台称为“Java 平台”。但我会修改我的答案。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-29
      • 2013-10-12
      • 2013-12-13
      相关资源
      最近更新 更多