46

{{ ... }}次のコードでブロックは何を意味しますか?

class X {

    private Y var1;

    private X() {
        Z context = new Z(new SystemThreadPool()) {{
            var1 = new Y();
        }};
    }

}
4

4 に答える 4

71

これは、二重中括弧の初期化と呼ばれます。(編集:リンクが削除され、ここにアーカイブされました

これは、匿名サブクラスを作成していることを意味し、二重中括弧内のコードは基本的にコンストラクターです。コレクションにコンテンツを追加するためによく使用されます。これは、本質的にコレクション定数を作成するための Java の構文がやや扱いにくいためです。

だからあなたはするかもしれません:

List<String> list = new ArrayList<String>() {{
  add("one");
  add("two");
  add("three");
}};

それ以外の:

List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

私は実際にはそれが好きではなく、これを行うことを好みます:

List<String> list = Arrays.asList("one", "two", "three");

したがって、その場合はあまり意味がありませんが、たとえば、便利なヘルパーを持たないマップの場合は意味があります。

于 2009-09-03T08:27:09.960 に答える
12

「外側」の中括弧は、匿名のサブクラスを作成していることを意味し、2番目の中括弧はオブジェクト初期化子です。初期化子は、クラスのコンストラクターの前に実行されますが、super呼び出しの後に実行されます(したがって、スーパークラスの初期化子の後にも実行されます)。非匿名クラスでも初期化子を使用できます。これは、final相互に呼び出すことができないコンストラクターが複数ある場合、または通常のフィールド初期化子で許可されるよりも複雑な初期化が必要なフィールドがある場合に、フィールドを開始する便利な方法です。

このクラスを検討してください。

class X extends Y{
    private final int lulz;

    private static boolean someCondition(){...}
    private static boolean danger() throws SomeException { ... }
    public X(A a) throws SomeException {
        super(a); 
        lulz = someCondition()? danger() : 0;
    }
    public X(B b) throws SomeException {
        super(b); 
        lulz = someCondition()? danger() : 0;
    }
}

次のように書き直すことができます。

class X extends Y{
    private final int lulz;

    private static boolean someCondition(){...}
    private static boolean danger() throws SomeException { ... }
    { // initalizer -- might throw SomeException!
        lulz = someCondition()? danger() : 0;
    }
    public X(A a) throws SomeException { super(a); }
    public X(B b) throws SomeException { super(b); }
}

初期化子がチェックされた例外をスローできる場合、すべてのコンストラクターはそれをスローできることを宣言する必要があります。

于 2009-09-03T08:41:04.637 に答える
4

次のように、匿名クラスを作成し、クラスInstance initializeridiomを使用しています。

class X {
    private Y var1;

    private X() {
        Z context = new Z(
               new SystemThreadPool()) {
                   {                        // This is the initialize idiom
                       var1 = new Y();      //
                   }                        //
               }
          );  // BTW you are missing ")"
    }
}
于 2009-09-03T08:41:14.153 に答える
3

前の回答で述べたように、二重中括弧の初期化は正しいです。

Java でインスタンス メンバーを初期化する特定の手法を使用します。これは、クラス コンストラクターのいずれかがアクティブ化されたときに実行されるコードの共有ブロックをクラス定義で定義する簡単な方法です。

この件に関するより広い視野のために、それを説明している公式のJavaドキュメントへのリンクを追加しています。

ドキュメントから:

インスタンス変数の初期化ブロックは、静的初期化ブロックと同じように見えますが、 static キーワードはありません。

{

// whatever code is needed for initialization goes here 

}

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

于 2014-05-11T10:00:10.607 に答える