【问题标题】:Why can't I use final fields within an instance initializer block?为什么我不能在实例初始化程序块中使用最终字段?
【发布时间】:2016-07-21 07:07:23
【问题描述】:

来自 Oracle 的 guide初始化字段(强调我的):

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

另外,来自 DOJ 的 article 关于 Java 中的实例初始化程序(重点是我的):

实例初始化块代码在构造函数中调用 super() 之后立即运行,换句话说,在所有超级构造函数都运行之后

考虑到这一点,为什么每次我尝试在实例初始化程序块中使用(分配的)最终字段时,我的编译器都会警告我,如下所示?

final class PpTitleBook implements TitleBook {
  private final Resources resources;
  private final Log log;

  PpTitleBook(Resources resources, Log log) {
    this.resources = resources;
    this.log = log;
  }

  {
    String[] resTitles = resources.getStringArray(R.array.titles);

    if (book().getAllKeys().isEmpty()) {
      for (int i = 0; i < resTitles.length; i++) {
        newTitle(resTitles[i]);
      }
    }
  }

除了上面显示的构造函数之外,我没有其他构造函数。那么警告背后的真正原因是什么?

【问题讨论】:

  • 答案在问题中:实例初始化块代码在构造函数中调用 super() 之后立即运行 因此,在构造函数的其余代码之前,初始化final 字段,被执行。这也正是警告信息所传达的内容。
  • 另见stackoverflow.com/questions/20593606/…(问题不好,但答案还可以)

标签: java initializer


【解决方案1】:

实例初始化块代码在构造函数代码之前执行,因此您的resources变量在被实例初始化块使用之前不会被初始化。

由于你只有一个构造函数,你可以把实例初始化块的代码移到构造函数中。

【讨论】:

  • 我对 Oracle 文档中的“将初始化程序块复制到每个构造函数中”这个词感到困惑。哦,那个班上曾经有不止一个演员。我正在重构过程中,这件事引起了我的好奇心。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-05-26
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多