这个问题严格来说是理论上的,但我无法找到答案。考虑这个简短的程序:
public class SBtst {
int i = 0;
public static void main(String[] args) {
new SBtst().rec();
}
public void rec() {
System.out.println("rec is called "+i++);
try {
rec();
} catch (StackOverflowError soe) {
System.out.println("completed "+soe.getStackTrace().length);
}
}
}
执行后,我得到的输出类似于:
rec is called 10472
rec is called 10473
rec is called 10474Recursion completed 1024
问题是:
为什么没有println()完成新行,因为根据我的理解,当执行下一个rec()调用时它应该抛出一个错误,并且它是在完成后的println()
为什么我只在stackTrace
数组中获得1024个元素,但i
等于10474?这是否意味着并非所有呼叫都在堆栈跟踪中?
答案 0 :(得分:8)
第1部分:
在the OpenJDK implementation中,println()
实现如下:
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
因此,对print(x)
的调用可能会溢出堆栈,并且StackOverflowError
将在没有调用newLine()
方法的情况下被提升。
第2部分:
来自Java API:
在某些情况下,某些虚拟机可能会从堆栈跟踪中省略一个或多个堆栈帧...一般来说,此方法返回的数组将包含每个将由printStackTrace打印的帧的元素。
因此,JVM可以自由地对堆栈跟踪中存储的堆栈帧数施加限制,例如1024.