2010-12-14 9 views
18

私はいくつかの継承されたコードを再検討していますが、設計上の決定に困惑しており、これをGoogleに適切な言葉で表すことはできません。私の前任者は次のようなブロックを使用します:Javaでは、なぜキーワードがないコードブロックを使用すると中括弧

public class ChildClass extends ParentClass { 
    { 
     inheritedVar = "someVal"; 
    } 

    public ChildClass(){ /* constructor exists */ } 
    // rest of code 
} 

キーワードのないコードブロックを宣言するポイントは何ですか?それは静的なブロックのように振る舞いません、私は信じていません。それはコンストラクタで設定する代わりに使用できますか?工場が使用されている場合(これはそうではありません)、これは何らかの効果がありますか?私はthis happening in Cに関連するスレッドを見つけましたが、推論(スコープ&変数宣言)はJavaに関連していないようです。

これの「理由」に関する考えやアイデアは感謝します。それを再因子化するのは簡単ですが、私はこの時点で興味があります。

答えて

29

初期化ブロックです。 (静的初期化子ブロックに関連する)このページで初期化インスタンスメンバーを参照してください:

http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

それはコンストラクタに代わるものです。コードを共有する方法として、複数のオーバーロードされたコンストラクタを提供するときに使用できます。

しかし、個人的には、匿名コードブロックに頼るのではなく、名前付きイニシャライザメソッドをコンストラクタで呼び出す方がはるかに明確です。コンパイラは、イニシャライザブロックをシーンの背後にあるすべてのコンストラクタにコピーしますが、メソッド宣言をインライン化するのと同じようにパフォーマンスが向上すると主張できます。

+1

+1このブロックの正しい使い方を指摘してください。 – birryree

+1

+1:名前付きイニシャライザメソッドについて私は同意します。しかし、コンストラクタが1つだけであることを考えると、コードベース内のこのブロック全体が無意味に見えます。 – Riggy

+0

@Riggy、それは確かに冗長です。 – Mike

-3

範囲。ブロック内で宣言された変数は、ブロックの後にスコープから外れます。変数のスコープを最小に保つと便利です。

また、匿名の内部クラスを定義する場合は、この構文をコンストラクタに使用します。

+0

メソッド本体の中にいれば、それは範囲であったでしょう。これはメソッドの外側でクラス本体にあります。他の答えをお読みください。 –

+0

-1これは誤った答えです。与えられた場合、それはイニシャライザブロックです。 –

16

initializer blockと呼ばれています。

初期化子ブロックインスタンス変数は単なる静的初期化子ブロックのように見えますが、静的なキーワードなしのため:

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

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

+0

あなたとマイクの両方が優れた回答を残しました。両方のリンクに感謝します。私が見つけたさまざまなクラスにそれぞれコンストラクタが1つしかないことを考えれば、多重オーバーロードされたコンストラクタについては考えていませんでした。 – Riggy

+0

小さなニックピック - コンパイラがイニシャライザブロックをコピーしないので、コンストラクタから特別なメソッドにコールが追加されます。これは{}が.classファイルになる方法です。 [静的イニシャライザブロックはメソッドになりました。] –

4

前任者はまだ学習していました。

これは、あなたが得る可能性が最も高い説明です。たぶん、ある時点で、このようにコードを分割する必要があったでしょう。言うのが難しい。コードは確実に次のように記述する必要があります。

​​

初期化ブロックについては、その目的はここでは他の回答で示しています。私はあなたが要求した「理由」に答える試みとして私の答えを投げた。残念ながら、本当の答えは、前任者に尋ねなければなりません。

+0

SOの読者にガーベッジコードを負わせることなく、ポイントを得るための最小限のコードしか掲載していませんでした。私は、コンストラクタがコード内に存在し、名前のないブロックがコンストラクタを置き換えていないことが明らかになるように、コンストラクタのみを含めました。ありがとう! – Riggy

+0

問題ありません。私はそれについて私の答えの部分を削除しました。 –

+4

あなたはそれが最良のコードではないことは間違いありません。私は、前任者が学んでいたことを示唆しています。他のdevs馬鹿と呼ぶ開発者は非常に多く、恥ずかしそうになったり、悪化したり、解雇されたりしないように、人々が間違いを隠すようにするだけです。私は「あなたの前任者はまだコード作成の仕方を学んでいた」と思っています。私は、開発者が正しいことを学ぶための安全な環境を作って、StackOverflowをそれらの1つにすべきだと強く感じています。あなたが手助けして、使用する言語を変更しますか? – Lunivore

関連する問題