13
public class Hello {
        public static final Hello h = new Hello();
        static int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

        }
        public static void main(String[] args) {

            h.print();
        }

    }

このコード出力は 5 , 0 です。理由が静的である場合、クラスで最初にロードされ、i は初期化され、j は初期化されません。ただし、静的を i から削除すると、

public class Hello {
        public static final Hello h = new Hello();
        int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

        }
        public static void main(String[] args) {

            h.print();
        }

    }

なぜ出力が5,5なのか。その後、i と j が初期化されます。理由を説明してください。

4

7 に答える 7

16

静的ブロックは順番に実行されます。

この時点i = 0ではまだ設定されていないため、最初に Hello オブジェクトを作成します。

これが行われた後にのみi = 5

静的ステートメントを上から下に読む必要があります。

于 2013-06-21T11:26:08.400 に答える
5

非静的変数はi、オブジェクトが作成されjた瞬間に初期化されます。Hello

public static final Hello h = new Hello();

質問の最初の部分で、ピーターはあなたに答えました。補足させてください。静的変数の順序を変更した場合:

static int i = 5;
public static final Hello h = new Hello();
int j  = i;

印刷されますが、印刷5, 5されません5, 0

于 2013-06-21T11:26:24.157 に答える
2

public static final Hello h = new Hello();と行を入れ替えてみてくださいstatic int i = 5;。最初にhelloオブジェクト(when i = 0, uninitialized)を初期化し、i. i期待される動作を得るために最初に初期化します。

于 2013-06-21T11:30:35.257 に答える
2

最初の例では次のようになります。

  • 静的メモリは 0 に初期化されます。この時点でHello.iは 0 に等しくなります。
  • Hello.hインスタンス化されます:
    • Hello.h.jHello.iの現在の値、つまり 0 に初期化されます。
  • Hello.i5 に初期化されます。

一方、2番目の例では:

  • Hello.hインスタンス化されます:
    • Hello.h.i5 に初期化されます。
    • Hello.h.jHello.h.iの現在の値、つまり 5 に初期化されます。
于 2013-06-21T11:39:46.517 に答える
1

ピーター・ローリーの答えは正しいです。あなたの混乱は、すべてが単一のクラスにあり、名前が似ているという事実から来ている可能性があるので、あなたの行動を視覚化する別の方法を提供したかったので、あなたのコードは論理的に次のコードと同等です:

public class Program {

    public static Hello h = new Hello();

        public static void main(String [] args) {
            h.i = 5;
            h.print();
        }
    }

    class Hello {

        public static int i = 0;
        private int j = i;

        public void print() {
            System.out.println(i+", "+j);
        }
    }
于 2013-06-21T13:53:59.300 に答える
0

Java は、クラスのロード時に静的な初期化を行います。したがって

public static final Hello h = new Hello();

Helloクラスが読み込まれると、 i = 5でデフォルト値がjのオブジェクトが作成されます。

変数ijの両方を非静的メンバーにすると、両方とも静的オブジェクト hのデフォルト値になります。

メインメソッドで新しいオブジェクトを作成する場合

Hello helloObj = new Hello();

それはあなたが望む結果を与えるでしょう。

于 2013-06-21T11:28:33.587 に答える
0

オラクル仕様のドキュメントから

クラスで宣言された静的初期化子は、クラスが初期化されるときに実行されます (§12.4.2)。クラス変数のフィールド初期化子 (§8.3.2) と共に、静的初期化子を使用してクラスのクラス変数を初期化できます。

于 2013-06-21T11:39:51.587 に答える