4

これは Java コードのスニペットです。

static {        
    ture = 9;       
}
static int ture;
{ // instance block 
    System.out.println(":"+ture+":");           
}

それはどのようにコンパイルされますか?初期化後に変数 ture の宣言が行われました。私の知る限り、静的ブロックとフィールドは表示順に実行されています。

そして、インスタンス ブロック内の値 9 が 3 回出力されたのはなぜですか? ちなみに、クラスのインスタンスは3回作成されています。それは宿題ではありません。私は認定のために Java を学んでいます。

4

3 に答える 3

11

最初の質問に関しては、静的ブロックは実際に表示された順序で処理されますが、静的ブロックの前に宣言が最初に処理されます。宣言は、初期化( JLS §12.4.2 )の前に発生するクラス ( JLS §12.3.2 ) の準備の一部として処理されます。学習目的では、JLS §12 全体、およびJLS §8、特に§8.6JLS §8.7が役立つ場合があります。( Ted Hoppに感謝します。また、これらのセクションを呼び出してくれた評判の悪い人に感謝します。)

引用されたコードには、2 番目の質問に答えるのに十分な情報がありません。(いずれにせよ、SO では、質問ごとに1 つの質問をするのが最善です。) しかし、たとえば:

public class Foo {
    static {     
        ture = 9;   
    }

    static int ture;

    {   // instance block   
        System.out.println(":"+ture+":");

    }

    public static final void main(String[] args) {
        new Foo();
    }
}

...インスタンスが 1 つしか作成されていないため、一:9: 度だけ出力します。行を削除すると、まったく出力されませんnew Foo();:9:3 回表示されている場合は、表示されていないコードで 3 つのインスタンスを作成しているように見えます。

于 2012-12-02T16:35:35.063 に答える
2

他の人が言ったように、宣言の場所は一般的に重要ではありません.

しかし、時には混乱を招くかもしれません:

class Z {
    static int i = j + 2;  // what should be the value of j here?
    static int j = 4;
}

したがって、Java は前方参照にいくつかの制限を追加します: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3

フィールドの使用法は割り当ての左側にあるため、あなたの例は許可されています。どうやら言語設計者は、それがあまり混乱しているとは考えていないようです。それにもかかわらず、可能であれば、常に前方参照を避けるべきです。

于 2012-12-02T18:43:45.173 に答える
2

静的初期化子は、表示された順序で実行され、宣言はまったく実行されないため、名前が付けられました。これが、コードが問題なくコンパイルされる理由です。クラス構造はコンパイル時に宣言からアセンブルされ、静的ブロックは実行時に、すべての宣言が処理されてからずっと後に実行されます。

于 2012-12-02T16:54:37.597 に答える