{{ ... }}
次のコードでブロックは何を意味しますか?
class X {
private Y var1;
private X() {
Z context = new Z(new SystemThreadPool()) {{
var1 = new Y();
}};
}
}
{{ ... }}
次のコードでブロックは何を意味しますか?
class X {
private Y var1;
private X() {
Z context = new Z(new SystemThreadPool()) {{
var1 = new Y();
}};
}
}
これは、二重中括弧の初期化と呼ばれます。(編集:リンクが削除され、ここにアーカイブされました)
これは、匿名サブクラスを作成していることを意味し、二重中括弧内のコードは基本的にコンストラクターです。コレクションにコンテンツを追加するためによく使用されます。これは、本質的にコレクション定数を作成するための 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");
したがって、その場合はあまり意味がありませんが、たとえば、便利なヘルパーを持たないマップの場合は意味があります。
「外側」の中括弧は、匿名のサブクラスを作成していることを意味し、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); }
}
初期化子がチェックされた例外をスローできる場合、すべてのコンストラクターはそれをスローできることを宣言する必要があります。
次のように、匿名クラスを作成し、クラス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 ")"
}
}
前の回答で述べたように、二重中括弧の初期化は正しいです。
Java でインスタンス メンバーを初期化する特定の手法を使用します。これは、クラス コンストラクターのいずれかがアクティブ化されたときに実行されるコードの共有ブロックをクラス定義で定義する簡単な方法です。
この件に関するより広い視野のために、それを説明している公式のJavaドキュメントへのリンクを追加しています。
ドキュメントから:
インスタンス変数の初期化ブロックは、静的初期化ブロックと同じように見えますが、 static キーワードはありません。
{
// whatever code is needed for initialization goes here
}
Java コンパイラは、イニシャライザ ブロックをすべてのコンストラクタにコピーします。したがって、このアプローチを使用して、複数のコンストラクター間でコードのブロックを共有できます。