Ano*_*aly 7 java instance-initializers
我的理解是你不能在声明变量之前引用变量,并且在构造函数创建对象之前,所有代码(包括实例初始值设定项)都在类的主体内但在任何方法之外的顺序执行(例外是static变量和初始化程序块,它们在程序开始时按顺序运行,以初始化整个类).那么,为什么以下代码编译(并运行!):
public class WhyIsThisOk {
{ a = 5; } // why is this ok???
int a = 10;
public WhyIsThisOk() {
}
public static void main(String[] args) {
WhyIsThisOk why = new WhyIsThisOk();
System.out.println(why.a); // 10
}
}
Run Code Online (Sandbox Code Playgroud)
从文档:
Java 编译器将初始化块复制到每个构造函数中。因此,这种方法可用于在多个构造函数之间共享代码块。
上面的说法有点误导,因为如果我们按照上面文档的解释,我们可以像这样重写原始代码:
public class WrongVersionOfWhyIsThisOk {
int a = 10;
public WhyIsThisOk (){
a = 5;
}
public static void main(String[] args){
WrongVersionOfWhyIsThisOk why = new WrongVersionOfWhyIsThisOk ();
System.out.println(why.a);
}
}
Run Code Online (Sandbox Code Playgroud)
但是运行WrongVersionOfWhyIsThisOk将产生 5 而不是原始代码产生的 10。
但实际上,初始化块和变量赋值都被复制到构造函数中:
public class RightVersionOfWhyIsThisOk {
int a;
public RightVersionOfWhyIsThisOk (){
a = 5;
a = 10;
}
public static void main(String[] args){
RightVersionOfWhyIsThisOk why = new RightVersionOfWhyIsThisOk ();
System.out.println(why.a);
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
这是详细描述初始化顺序和构造函数调用的文档:
4) 执行该类的实例初始化器和实例变量初始化器,将实例变量初始化器的值分配给相应的实例变量,按照它们在类的源代码中以文本形式出现的从左到右的顺序。如果执行这些初始化程序中的任何一个导致异常,则不会处理进一步的初始化程序,并且此过程会突然完成并出现相同的异常。否则,继续第 5 步。
5) 执行此构造函数的其余部分。如果该执行突然完成,那么这个过程也会出于同样的原因突然完成。否则,此过程将正常完成。
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |