2016-04-07 10 views
7

私はまだJavaの学習曲線にあります。私は小さなテストクラスを作成した初期化子ブロックのビットより多くを理解するために:非静的イニシャライザブロック - もう少し制御できますか?

public class Script { 

    { 
     Gadgets.log("anonymous 1"); 
    } 

    public Script() { 
     Gadgets.log("constructor"); 
    } 

    { 
     Gadgets.log("anonymous 2"); 
    } 
} 

私はインスタンスを作成するときに、私はこのログを取得:

Script: anonymous 1 
Script: anonymous 2 
Script: constructor 

これは私に語った、両方の初期化ブロックは、前に実行しますコンストラクタをソースコード内に現れる順に実行します(静的初期化子と同じ)。 私が知りたいことは次のとおりです。この行動に対してもう少しコントロールできますか? (source)Javaドキュメントが言うので:インスタンスの変数は静的な 初期化子ブロックのように見えますが、静的なキーワードのない

初期化子ブロック:

{ 
    // whatever code is needed for initialization goes here 
} 

のJavaコンパイラのコピーの初期化子をすべてのコンストラクタにブロックします。したがって、 このアプローチは、複数の コンストラクタ間でコードブロックを共有するために使用できます。

したがって、「初期化ブロックをすべてのコンストラクタにコピーする」という意味はどういう意味ですか?私のログによると、彼らは各コンストラクタの最初にとコピーされているようです。これは正しいですか?彼らはそれぞれのコンストラクタのENDにコピーされた場合も、完全に理にかなって複数のコンストラクタとの間のこのようなブロックを共有

(それは私が期待して何が私の2匿名)。 は、もう少しそれらのブロックを制御する方法はありますか私の唯一のオプションは、私は、各コンストラクタの最後で一般的なタスクを実行したい場合は、すべてのコンストラクタで呼び出されるという名前のメソッドを書くの「古典的」な方法ですか?

+2

コンストラクタの前にコピーされるコードの問題は何ですか? –

+0

コンストラクタは、コンストラクタのコードより前に実行する必要があり、最後には必要ではないことが予想されます。コンストラクタが既に初期化されている変数に依存することができるからです。 – mah

+3

実際、*初期化ブロック*はコンストラクタに**コピー**され、 'super'の後で残りのコンストラクタボディの前に実行されます。 –

答えて

11

コンストラクタは次の順序で実行します。

  1. super()呼び出し、暗黙的または明示的。
  2. 可変イニシャライザとイニシャライザブロックは、ソースコード内に現れる順番で並んでいます。
  3. コンストラクタの残りの部分。

これはJLSで指定されており、変更することはできません。

this()

コールが存在する場合、それは(1)置換し、(2)。

+0

ありがとうございます。私のログを見ると、私はこれ以上のコントロールがないと思っていました。今私はそれを知っている。 – Grisgram

関連する問題