初始值设定项与构造函数在 Java 中的使用

因此,我最近一直在提高我的Java技能,并发现了一些我以前不知道的功能。静态初始值设定项和实例初始值设定项就是这样两种技术。

我的问题是,什么时候会使用初始值设定项而不是在构造函数中包含代码?我想到了几个明显的可能性:

  • static/instance 初始值设定项可用于设置“final”static/instance 变量的值,而构造函数不能

  • 静态初始值设定项可用于设置类中任何静态变量的值,这应该比在每个构造函数的开头有一个“if (someStaticVar == null) // do stuff”代码块更有效

这两种情况都假定设置这些变量所需的代码比简单的“var = value”更复杂,否则似乎没有任何理由在声明变量时使用初始值设定项而不是简单地设置值。

然而,虽然这些不是微不足道的收益(特别是设置最终变量的能力),但似乎确实存在相当有限的情况下应该使用初始值设定项的情况。

当然,对于构造函数中所做的许多操作,人们当然可以使用初始值设定项,但我真的看不出这样做的原因。即使一个类的所有构造函数都共享大量代码,对我来说,使用私有 initialize() 函数似乎比使用初始值设定项更有意义,因为它不会在编写新构造函数时锁定您运行该代码。

我错过了什么吗?是否还有其他一些情况应该使用初始值设定项?或者它真的只是一个相当有限的工具,用于非常特殊的情况?


答案 1

静态初始值设定项与 cletus 提到的有用,我以相同的方式使用它们。如果您有一个要在加载类时初始化的静态变量,那么静态初始值设定项就是要走的路,特别是因为它允许您执行复杂的初始化并且仍然具有静态变量 be 。这是一个巨大的胜利。final

我发现“if (someStaticVar == null) // do stuff”很混乱,容易出错。如果它以静态方式初始化并声明,则可以避免它被.finalnull

但是,当你说:

static/instance 初始值设定项可用于设置“final”static/instance 变量的值,而构造函数不能

我假设你说的是两者:

  • 静态初始值设定项可用于设置“final”静态变量的值,而构造函数不能
  • 实例初始值设定项可用于设置“final”实例变量的值,而构造函数不能

你在第一点上是对的,在第二点上是错误的。例如,您可以执行以下操作:

class MyClass {
    private final int counter;
    public MyClass(final int counter) {
        this.counter = counter;
    }
}

此外,当构造函数之间共享大量代码时,处理此问题的最佳方法之一是链接构造函数,并提供默认值。这使得正在做什么非常清楚:

class MyClass {
    private final int counter;
    public MyClass() {
        this(0);
    }
    public MyClass(final int counter) {
        this.counter = counter;
    }
}

答案 2

匿名内部类不能有构造函数(因为它们是匿名的),所以它们非常适合例如初始值设定项。