9

可能重复:
Java 中的双大括号初始化是什么?

在查看一些遗留代码时,我遇到了一些非常令人困惑的事情:

 public class A{
      public A(){ 
          //constructor
      }
      public void foo(){
            //implementation ommitted
      }
 }

 public class B{
      public void bar(){
           A a = new A(){ 
                { foo(); }
           }
      }
 }

在调试模式下运行代码后,我发现在{ foo() }调用构造函数之后调用了匿名块A()。上述功能与执行有何不同:

 public void bar(){
       A a = new A();
       a.foo();
 }

? 我认为它们在功能上是等效的,并且认为后一种方式是编写代码的更好/更清洁的方式。

4

3 回答 3

8
 { foo(); }

被称为实例初始化器

为什么?

按照java教程

Java 编译器将初始化程序块复制到每个构造函数中。因此,这种方法可用于在多个构造函数之间共享代码块。

于 2013-01-08T20:44:39.320 回答
4

“在以下情况下,实例初始化程序是实例变量初始化程序的有用替代方案:(1) 初始化程序代码必须捕获异常,或 (2) 执行无法用实例变量初始化程序表达的奇特计算。当然,您可以总是这样写构造函数中的代码。但是在一个有多个构造函数的类中,您必须在每个构造函数中重复代码。使用实例初始化器,您只需编写一次代码,无论使用什么构造函数创建都会执行对象。实例初始化器在匿名内部类中也很有用,它根本不能声明任何构造函数。来源

这也被引用在这个答案中。

于 2013-01-08T20:47:48.287 回答
2

除非对象的运行时类被访问(通过调用getClass())并且由于某种原因需要不同于A(例如因为它用作超类型令牌),否则确实没有区别,并且foo()在构造后简单地调用确实是比较常见的成语。

于 2013-01-08T20:49:37.477 回答