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

“外部”大括号意味着您正在创建一个匿名子类,第二个大括号是对象初始化器。初始化程序在类的构造函数之前运行,但在任何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 初始化r 惯用语,如下所示:

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 回答