关于java:实例初始化器与构造函数有何不同?

How is an instance initializer different from a constructor?

换句话说,为什么需要实例初始化器? 在构造函数上编写实例初始化程序有什么区别或优势?


这似乎解释得很好:

Instance initializers are a useful alternative to instance variable
initializers whenever:

  • initializer code must catch exceptions, or

  • perform fancy calculations that can't be expressed with an instance variable initializer. You could, of course, always write such code in
    constructors.

But in a class that had multiple constructors, you would have to repeat the code in each constructor. With an instance initializer, you
can just write the code once, and it will be executed no matter what
constructor is used to create the object. Instance initializers are
also useful in anonymous inner classes, which can't declare any
constructors at all.

来自:爪哇JavaWorld对象初始化。


就对象生命周期而言,没有区别。两者都在构造时调用,逻辑上初始化块可以被视为构造的一部分。

从语义上讲,初始化程序是一个很好的工具,有以下几个原因:

初始化程序可以通过将初始化逻辑保持在初始化变量旁边来提高代码可读性:

1
2
3
4
5
6
7
8
9
10
   public class Universe {
       public int theAnswer;
       {
         int SIX = 6;
         int NINE = 7;
         theAnswer = SIX * NINE;
       }

       // a bunch of other vars
   }

VS

1
2
3
4
5
6
7
8
9
10
11
12
13
   public class Universe {
       public int theAnswer;

       // a bunch of other vars

       public Universe() {
         int SIX = 6;
         int NINE = 7;
         theAnswer = SIX * NINE;

         // other constructor logic
       }
   }

无论如何都会调用初始化程序
使用哪个构造函数。

初始化程序可以匿名使用
内部类,构造函数
不能。


当你有许多构造函数并希望为每个构造函数执行一些公共代码时,可以使用实例初始化器。因为它是为所有构造函数调用的。


当我们使用匿名内部类时,可以看到实例初始化器相对于构造函数的真正优势。

匿名内部类不能有构造函数(因为它们是匿名的),因此它们非常适合实例初始化程序。


我会避免使用实例初始化程序习惯用法 - 它对变量初始化程序的唯一真正优势是异常处理。

并且因为init方法(可以从构造函数调用)也可以进行异常处理并集中构造函数设置代码,但是它具有可以对构造函数参数值进行操作的优点,我会说实例初始化程序是冗余的,因此是避免。


Initializer是在构造函数之间共享代码的方法,如果初始化程序与变量声明一起使用,它会使代码更具可读性。

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