以下代码中{{ ... }}
阻止的含义是什么?
class X {
private Y var1;
private X() {
Z context = new Z(new SystemThreadPool()) {{
var1 = new Y();
}};
}
}
答案 0 :(得分:66)
它被称为double curly brace initialization。 (编辑:已删除链接,archived here)
这意味着你正在创建一个匿名子类,双括号内的代码基本上是一个构造函数。它通常用于向集合添加内容,因为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");
因此,在这种情况下它没有多大意义,而对于没有方便助手的地图来说却是如此。
答案 1 :(得分:11)
“外部”括号表示您正在创建一个匿名子类,第二个大括号是对象初始值设定项。初始化程序在类的构造函数之前运行,但是在任何super
调用之后(因此也在任何超类初始化程序之后)。您也可以在非匿名类中使用初始化程序,如果您有多个不能相互调用的构造函数,或者需要比通常的字段初始化程序允许的更复杂的初始化的字段,这是启动final
字段的便捷方式。 / p>
考虑这个课程:
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); }
}
如果初始化程序可以抛出已检查的异常,则所有构造函数都必须声明它们可以抛出它。
答案 2 :(得分:4)
您正在创建anonymous class并使用class Instance initialize惯用语,如下所示:
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 ")"
}
}
答案 3 :(得分:1)
如前所述,双花括号初始化是正确的。
它使用特定技术在Java中初始化实例成员。它是在类定义中定义一个共享代码块的简便方法,该代码块将在激活任何类构造函数时运行。
我正在添加描述它的official Java documentations链接,以便更广泛地了解该主题。
实例变量的初始化块看起来就像静态 初始化块,但没有static关键字:
{
// whatever code is needed for initialization goes here
}
Java编译器将初始化程序块复制到每个构造函数中。 因此,这种方法可用于共享一段代码 多个构造函数。