Java 使用以下双括号的构造函数调用是什么?

Java 使用以下双括号的构造函数调用是什么?,java,syntax,constructor,anonymous-class,Java,Syntax,Constructor,Anonymous Class,不幸的是,我已经五年没有编写Java代码了,我完全不记得下面的代码是如何工作的或为什么工作的 我偶然发现了一个类似的例子,并将其分解为以下内容。重点放在注释下面的部分:我不知道构造函数符号后面是双括号中的块。不幸的是,我在Java文档或使用Google时找不到任何东西(我应该用Google搜索什么词?) 下面是我的问题: 这个符号/语法是如何命名的 我在哪里可以阅读有关它的文档 如果有人能给我第一个问题的答案,我想/希望我能自己回答第二个问题 明确地说:我知道输出是johnjohnson;)但我

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

我偶然发现了一个类似的例子,并将其分解为以下内容。重点放在注释下面的部分:我不知道构造函数符号后面是双括号中的块。不幸的是,我在Java文档或使用Google时找不到任何东西(我应该用Google搜索什么词?)

下面是我的问题:

  • 这个符号/语法是如何命名的
  • 我在哪里可以阅读有关它的文档 如果有人能给我第一个问题的答案,我想/希望我能自己回答第二个问题

    明确地说:我知道输出是
    johnjohnson
    ;)但我不知道它为什么会起作用。

    这被称为:

    第一个支架将创建一个新支架 第二类,第二类 声明实例初始值设定项块 当匿名内部 类被实例化。这种 初始化程序块正式称为 “实例初始值设定项”,因为它 在实例范围内声明 类的名称--“静态初始值设定项” 是一个相关概念,其中 关键字static放在 开始块的支架,以及 尽快在类级别执行 当类加载器完成加载时 类别(在中指定) ) 初始化程序块可以使用任何 方法、字段和最终变量 在包含范围中可用,但 人们必须警惕这样一个事实: 初始化程序在之前运行 构造器

    这仅适用于非最终版本 类,因为它创建了 匿名子类


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

    MyTest tester = new MyTest() {
      {
        setName("John Johnson");
      }
    };
    
    这里所看到的被称为双括号初始化。您有一个类
    MyTest
    的匿名内部子类,以及一个初始值设定项块,该块包含在构造对象时运行的代码

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

    话虽如此,这么做有点难看。有更好的办法。但是,我偶尔也会使用它,通常在以下习惯用法中创建一个不变的映射:

    final Map<String, Integer> textToInt = Collections.unmodifiableMap(new HashMap<String, Integer>() {{
        put("one", 1);
        put("two", 2);
        // etc
    }});
    
    final-Map textToInt=Collections.unmodifiableMap(新HashMap()){{
    付诸表决(“一”,1);
    放(二),二;;
    //等
    }});
    
    它创建一个新映射,覆盖它,在初始值设定项块中向它添加一些值,并将它包装在一个不可修改的映射中

    MyTest tester = new MyTest() {{
       setName("John Johnson");
    }};
    

    MyTest tester = new MyTest();
    tester.setName("John Johnson");
    

    当我第一次在Usenet上看到它时,我不得不看了一会儿才意识到发生了什么。一旦你知道了它是什么,这是显而易见的。我不久前就看到了这个巧妙的把戏,但我也看到不少免责声明说,用它打破东西很容易/不太可靠。如果我要尝试使用它,我一定会认为,A)我必须向每个人解释它,从那时起,B)我必须做一些研究来理解使用这个模式的所有含义。谢谢大家的快速和有益的答复!这些不一样。他们的成绩不一样。创建MyTest的一个实例。另一个创建MyTest的匿名子类的实例。如果你的等值方法看起来是这样的:公有布尔等于(object object){if(At.C.O.MyTest.C类){返回false;} / /一些更多的检查…}然后它不会认为它们是相同的。@ MangSt,我想你应该说它们是“功能等同于大多数目的”;你必须在这方面有点迂腐--工程师的本性和所有。。。
    MyTest tester = new MyTest();
    tester.setName("John Johnson");