最初にStackOverFlowError
が発生すると、 last への呼び出しdoAnything()
がキャンセルされ、最後の から catch ブロックに制御が戻されdoAnything()
ます。
ただし、スタックはまだ実質的にいっぱいであるため、呼び出しの単純な事実は、スタックに値をプッシュしてから関数を呼び出す必要があるため、System.out.print("y")
別の原因になります。StackOverflowError
print()
したがって、別のことが再び発生し、戻り値が前の;StackOverflowError
の catch{} ブロックで返されるようになりました。への単一の呼び出しを実行するために必要なスタック領域の必要性が、からの呼び出しを返すことによって解放される領域の量よりも大きいため、doAnything()
別のことが起こります。StackOverflowError
System.out.println("y")
doAnything()
呼び出しを実行するのに十分なスペースがスタックにある場合にのみ、System.out.print("y")
このプロセスが停止し、catch ブロックが正常に完了します。次のコードを実行すると、それを確認できます。
public class Principal3b {
static int a = 0;
static int i = 0;
static int j = 0;
public static void main(String[] args) {
System.out.println("X");
doAnything();
System.out.println("Y");
System.out.println(i);
System.out.println(j);
}
private static void doAnything() {
a++;
int b = a;
try {
doAnything();
} catch (final Error e) {
i++;
System.out.println(a);
System.out.println(b);
j++;
}
}
}
println(a)
aの代わりにa が使用されていることに注意してくださいprint(a)
。したがって、すべてが正常に実行された場合、各値の後に新しい行を出力する必要がありますa
。
ただし、実行すると、次の結果が得られます。
X
62066206620662066206620662066206
6190
Y
17
1
これは、catch ブロックの実行が 17 回試行されたことを意味します。これらの catch ブロックの実行のうち、9 つは StackOverflowError を生成する前に何も出力できません。7 は 6190 の値を出力できますが、その後に改行を出力できず、エラーが再び発生します。最後に、6190 の値とその後の改行の両方を出力できるものがあります。したがって、最終的にその catch ブロックが新しい StackOverflowError なしで完了し、コール スタックに正常に戻ることを許可します。
StackOverflowError を扱っているため、これらの数値は単なる例であり、マシン間だけでなく実行間でも大きく異なります。任意の種類の命令を追加または削除するという単純な事実によっても、これらの値が変化するはずです。ただし、ここで見られるパターンは同じままである必要があります。