1. ホーム
  2. java

なぜこの文はStackOverflowErrorを投げないのですか?

2023-11-12 15:31:46

質問

私はちょうどこれを見ました 奇妙な の部分を見ました。私は、それが結果的に StackOverflowError が投げられると思ったのですが、そうではありませんでした...。

public class Node {
    private Object one;
    private Object two;
    public static Node NIL = new Node(Node.NIL, Node.NIL);

    public Node(Object one, Object two) {
        this.one = one;
        this.two = two;
    }
}

例外が発生すると思っていたのですが、その理由は Node.NIL が自分自身を参照して構築しているため、例外が発生すると思っていました。

なぜそうならないのか、それがわからないのです。

どのように解決するのですか?

NIL は静的変数です。クラスが初期化されるときに一度だけ初期化されます。初期化されるとき、1つの Node のインスタンスが作成されます。その作成された Node が作成されても、他の Node のインスタンスを生成しないので、呼び出しの無限連鎖は起こりません。渡される Node.NIL を渡すと、コンストラクタの呼び出しに null を渡すのと同じ効果があります。 Node.NIL はコンストラクタが呼ばれたときにはまだ初期化されていないからです。したがって public static Node NIL = new Node(Node.NIL, Node.NIL); と同じです。 public static Node NIL = new Node(null, null); .

一方、もし NIL がインスタンス変数であった場合(そして、引数として Node のインスタンスが生成されるたびに初期化されることになります(コンパイラがそれをコンストラクタに渡すことを禁止していたため)。 Node のインスタンスが作成されるたびに初期化され、その結果、新しい Node インスタンスが作成され、その作成によって別の NIL インスタンス変数が初期化され、コンストラクタ呼び出しの無限連鎖が起こり、最後は StackOverflowError .