web-dev-qa-db-ja.com

これがメソッドの外にある中括弧({})のJavaコード)であるのはなぜですか?

Java認定試験の準備をしていますが、模擬テストの1つでこのようなコードを見ました。

class Foo {  
    int x = 1;  
    public static void main(String [] args) {  
        int x = 2;  
        Foo f = new Foo();  
        f.whatever();  
    }  
    { x += x; }  // <-- what's up with this?
    void whatever() {  
        ++x;  
        System.out.println(x);  
    }  
}

私の質問は...メソッドの外で中括弧でコードを書くことは有効ですか?これらの影響は何ですか(もしあれば)?

30
nairdaen

から借りた ここ -

通常、コンストラクターでインスタンス変数を初期化するコードを配置します。コンストラクターを使用してインスタンス変数を初期化する代わりに、初期化ブロックとfinalメソッドの2つの方法があります。インスタンス変数のイニシャライザーブロックは、静的イニシャライザーブロックと同じように見えますが、staticキーワードはありません。

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

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

ディスカッションもご覧ください ここ

34
Shankar Raju

これは、クラスのインスタンスがロード/作成されている間に実行され、クラスのメンバープロパティを初期化するために使用される初期化ブロックです(Java http:// download.Oracle.com/javase/tutorial/Java/javaOO/initial.html )。必要な数のブロックを含めることができ、それらは上から下にインスタンス化されます。

インスタンスブロックに加えて、静的メンバーを初期化するために必要な数の静的ブロックを持つことができます。それらは次のように宣言されます。

public class Initialization {

    static int b = 10;

    int a = 5;

    static {
        b = -9;
    }

    {
        a += 2;
    }

    public static void main(String[] args) throws Exception {

        System.out.println(ClientVoting.b);
        System.out.println(new ClientVoting().a);
        System.out.println(ClientVoting.b);
        System.out.println(new ClientVoting().a);

    }

    static {
        b = 1;
    }

    {
        a++;
    }
}

クラスの初期化中に、静的メンバー「b」は10として初期化され、最初の静的スコープはその値を-9に変更し、その後1に変更します。これはクラスのロード中に1回だけ実行されます。これは、mainメソッドの最初の行が初期化される前に実行されます。

一方、クラスと同様の例は、インスタンス参照「a」です。 Aは5として初期化され、インスタンスブロックはそれを7に更新し、最後のブロックは8に更新します。予想どおり、静的メンバーはこのコードで1回だけ初期化されますが、インスタンスブロックは新しいインスタンスを作成するたびに実行されます。

この例の出力は18 18です。

11

初期化ブロック です。インスタンス変数を設定するために使用されます。コンストラクターではなく初期化ブロックを使用する動機は、冗長なコードの記述を防ぐことです。 Javaコンパイラは、ブロックの内容を各コンストラクタにコピーします。

7
blackcompe