这个构造函数调用以下双括号是什么?

kle*_*ker 15 java syntax constructor anonymous-class

不幸的是,我没有编写Java大约五年,我完全不记得下面的代码如何或为什么工作.

我偶然发现了一个类似的例子并将其分解为此.重点是注释下面的部分:我没有得到构造函数符号,后面是双括号中的块.不幸的是,我无法在Java文档中找到任何内容或使用Google(我应该使用哪些词?).

package syntaxtest;

public class Main {

    public static void main(String[] args) {

        // What kind of notation is this?
        MyTest tester = new MyTest() {{
            setName("John Johnson");
        }};

        System.out.println(tester.getName());
    }
}


class MyTest {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以这是我的问题:

  1. 如何调用这种符号/语法?
  2. 我在哪里可以阅读一些有关它的文档?

我想/希望如果有人能够为我提供第一个问题的答案,我将能够自己回答第二个问题.

说清楚:我知道输出是John Johnson;)但我不知道它为什么有效.

And*_*are 21

这称为双括号初始化:

第一个大括号创建一个新的AnonymousInnerClass,第二个大括号声明在实例化匿名内部类时运行的实例初始化程序块.这种类型的初始化程序块正式称为"实例初始化程序",因为它是在类的实例范围内声明的 - "静态初始化程序"是一个相关的概念,其中关键字static放在启动块的括号之前,并且一旦类加载器完成加载类,就在类级别执行(在http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6中指定 )初始化块可以使用包含范围中可用的任何方法,字段和最终变量,但必须警惕初始化程序在构造函数之前运行的事实.

这仅适用于非final类,因为它创建了一个匿名子类.


jqn*_*qno 15

让我们以不同的方式布局代码:

MyTest tester = new MyTest() {
  {
    setName("John Johnson");
  }
};
Run Code Online (Sandbox Code Playgroud)

你在这里看到的是双支撑初始化.您有一个匿名的类的内部子类MyTest,以及一个初始化块,它是一个包含在构造对象时运行的代码的块.

通常,您会将这些代码放在构造函数中,但由于匿名内部类不能具有构造函数,因此这是保证代码在应该运行时运行的唯一方法.

话虽如此,这样做有点难看.有更好的方法.但是,我偶尔会自己使用它,通常在下面的习惯用法中创建一个不可变的地图:

final Map<String, Integer> textToInt = Collections.unmodifiableMap(new HashMap<String, Integer>() {{
    put("one", 1);
    put("two", 2);
    // etc
}});
Run Code Online (Sandbox Code Playgroud)

这将创建一个新映射,覆盖它,在初始化程序块中为其添加一些值,并将其包装在不可修改的映射中.