据我所知,在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()
之前),尽管它是构造函数而不是方法?
保存构造函数状态和方法状态之间是否存在显着差异?
答案 0 :(得分: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)
答案 1 :(得分: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();
}
}
答案 2 :(得分:1)
是。对构造函数的调用就像常规方法一样使用堆栈。