new Class(...){{...}}初始化习语的含义

Vic*_*kin 44 java initialization double-brace-initialize

{{ ... }}块在以下代码中的含义是什么?

class X {

    private Y var1;

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

}
Run Code Online (Sandbox Code Playgroud)

cle*_*tus 68

它被称为双花括号初始化.(编辑:链接删除,存档在这里)

这意味着你正在创建一个匿名子类,双括号内的代码基本上是一个构造函数.它通常用于向集合添加内容,因为Java用于创建本质上是集合常量的语法有点尴尬.

所以你可能会这样做:

List<String> list = new ArrayList<String>() {{
  add("one");
  add("two");
  add("three");
}};
Run Code Online (Sandbox Code Playgroud)

代替:

List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
Run Code Online (Sandbox Code Playgroud)

我实际上不喜欢这样,喜欢这样做:

List<String> list = Arrays.asList("one", "two", "three");
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下它没有多大意义,而对于没有方便助手的地图来说也是如此.

  • 请注意,Arrays.asList()返回java.util.Arrays.ArrayList.ArrayList而不是java.util.ArrayList,它具有有限的功能. (8认同)
  • 这种技术很棘手并且有一些注意事项.最终可能会破坏equals()合同或增加内存使用而没有任何充分的理由.除非你完全知道自己在做什么,否则最好避免双括号初始化.请查看[this](http://www.ayp-sd.blogspot.com/2012/12/double-brace-initialization-in-java.html)帖子了解更多详情. (3认同)

gus*_*afc 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

它可以改写为:

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); }
}
Run Code Online (Sandbox Code Playgroud)

如果初始化程序可以抛出已检查的异常,则所有构造函数都必须声明它们可以抛出它.