2016-04-01 41 views
0

从Oracle的guide初始化场(重点煤矿):为什么我不能在实例初始化块中使用final字段?

Java编译器副本初始化语句块到每一个构造函数。因此,这种方法可以用来在多个构造函数之间共享一段代码。

此外,从司法部的article关于Java实例初始化(重点煤矿):

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

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

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]); 
     } 
    } 
    } 

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

+3

答案在于以下问题:*实例初始化块代码在构造函数中调用super()之后运行*因此,在构造函数的其余代码初始化最终字段之前执行。而这正是警告信息所说的。 –

+0

另请参见http://stackoverflow.com/questions/20593606/how-non-static-initializer-block-invoked?rq=1(问题是坏的,但答案是好的) –

回答

5

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

由于您只有一个构造函数,因此您可以将实例初始化程序块的代码移动到构造函数中。

+0

我很困惑与单词“将初始化块复制到Oracle的文档中的每个构造函数中“。噢,上课时曾经有过一个以上的ctor。我正在进行重构,这一事件引起了我的好奇心。谢谢。 – ridsatrio

+0

@ridsatrio不客气 – Eran

相关问题