二重括弧の初期化の理解
4161 ワード
偶然初期化方式を見て、とても珍しいと感じました.
HashMapの初期化などの他の集合もあります.
この方式は先にnewがオブジェクトを出すよりも、もう1本のaddで、より簡潔で優雅に見えます.最初は何の原理も考えられなかったが、後で調べてみると、この方法は二重カッコ初期化(double brace initialization)や匿名内部クラス初期化法と呼ばれ、実際には巧みな方法であることが分かった.
理解:
ここでArrayListの例として説明すると、まず第1層のカッコは、ArrayListに継承された匿名の内部クラス(Anonymous Inner Class)を定義する.
第2層の括弧は、実際にはこの匿名の内部クラスインスタンス初期化ブロック(Instance Initializer Block)(または非静的初期化ブロックと呼ばれる)である.
このArrayListのサブクラスのインスタンスをnewによって取得し、ArrayListの参照にアップコンバートします.実際にはArrayListのサブクラスの参照を得ていますが、このサブクラスはArrayListに比べて機能的な変更はありません. は、参照を取得してから値を付与するのではなく、自身がデータを装着しているサブクラスであると考えられる.
次にクラスをカスタマイズし、この方法で初期化します.
注意:この方法は、コードをある程度簡潔にするが、同時に可読性を低下させる可能性がある.メモリの漏洩も発生し、シーケンス化時に問題が発生する可能性があります(テストされていません).
コメントエリアの友人のコメントに感謝し、この問題をもっと深く理解させていただきました.^^;
// A、B、C
ArrayList<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
HashMapの初期化などの他の集合もあります.
Map map = new HashMap() {{
put("Name", "Unmi");
put("QQ", "1125535");
}};
この方式は先にnewがオブジェクトを出すよりも、もう1本のaddで、より簡潔で優雅に見えます.最初は何の原理も考えられなかったが、後で調べてみると、この方法は二重カッコ初期化(double brace initialization)や匿名内部クラス初期化法と呼ばれ、実際には巧みな方法であることが分かった.
理解:
ここでArrayListの例として説明すると、まず第1層のカッコは、ArrayListに継承された匿名の内部クラス(Anonymous Inner Class)を定義する.
// ArrayList ,
new ArrayList<String>(){
//
};
第2層の括弧は、実際にはこの匿名の内部クラスインスタンス初期化ブロック(Instance Initializer Block)(または非静的初期化ブロックと呼ばれる)である.
new ArrayList<String>(){
{
// ,
}
};
このArrayListのサブクラスのインスタンスをnewによって取得し、ArrayListの参照にアップコンバートします.
ArrayList<String> list = new ArrayList<String>() {{}};
次にクラスをカスタマイズし、この方法で初期化します.
class Person{
protected String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
...
public static void main(String[] args) {
Person p = new Person(){
{
name = "xiaoming"; // setName()
age = 3; // setAge()
}
};
System.out.println(p.getName() + p.getAge());
}
注意:
コメントエリアの友人のコメントに感謝し、この問題をもっと深く理解させていただきました.^^;