変数 Java 静的初期化の動作



java 初期化ブロック (6)

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();
        }

    }

reasonがクラス内で最初に静的ロードを行い、iが初期化され、jが初期化されていない場合、このコード出力は5、0です。

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が初期化されます。 その理由を説明してください。


Answer #1

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

public static final Hello h = new Hello();

質問の最初の部分では、 Peterがあなたに答えてくれました。 それを補完しましょう。 静的変数の順序を変更した場合

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

5, 0なく5, 0


Answer #2

Javaはクラスロード時に静的初期化を行います。 だから

public static final Hello h = new Hello();

Helloクラスがロードされたときに、 i = 5 、デフォルト値jのオブジェクトを作成します。

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

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

Hello helloObj = new Hello();

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


Answer #3

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

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

これが終わって初めてi = 5

あなたは上から下に静的文を読む必要があります。


Answer #4

Peter Lawreyの答えは正しいです、あなたの混乱はすべてが単一のクラスに属しているという事実から来ているかもしれません、そして名前はこんな感じです。

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);
        }
    }

Answer #5

これがあなたの最初の例で起こることです:

  • 静的メモリは0に初期化されます。この時点で、 Hello.iは0です。
  • Hello.hがインスタンス化されます。
    • Hello.hjは、 Hello.iの現在の値、つまり0に初期化されます。
  • Hello.iは5に初期化されています。

一方、2番目の例では、

  • Hello.hがインスタンス化されます。
    • Hello.hiは5に初期化されています。
    • Hello.hjは、 Hello.hiの現在の値、つまり5に初期化されます。

Answer #6

オラクルスペックのドキュメントから

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





static