英文:
Unpredictable behaviour of an initializer block
问题
public class Ex14 {
static String strDef = "在定义的地方";
static String strBlock;
{ strBlock = "在一个块中"; }
public static void main(String[] args) {
System.out.println(Ex14.strDef);
System.out.println(Ex14.strBlock);
Ex14 test = new Ex14();
System.out.println(test.strBlock);
System.out.println(Ex14.strBlock);
}
}
结果:
$ java Ex14
在定义的地方
null
在一个块中
在一个块中
如果我将块与注释部分互换,两个语句都会被打印出来。换句话说,我无法理解发生了什么。
问题:
-
在初始化块内部,该变量是非静态的。如果它没有与静态声明混在一起,为什么编译器甚至没有警告我?
-
当创建一个实例时,strBlock 不再为 null。我无法理解为什么?
-
无论如何,我在这里什么都无法理解。请问,你能否在某种程度上进行解释?
英文:
public class Ex14 {
static String strDef = "At the point of definition";
static String strBlock;
{ strBlock = "In a block";}
public static void main (String [] args){
System.out.println(Ex14.strDef);
System.out.println(Ex14.strBlock);
Ex14 test = new Ex14();
System.out.println(test.strBlock);
System.out.println(Ex14.strBlock);
}
}
Result:
$ java Ex14
At the point of definition
null
In a block
In a block
If I switch the block with the commented one, both statements are printed. In other words, I just
Well, I can't catch what is going on here.
Questions:
-
Inside the initializer block the variable is non-static. If it is
not anyhow mixed with that static declaration, why the compiler
didn't even warn me? -
When an instance was created, strBlock is not null anymore. I can't
catch why? -
Anyway, I can't understand anything here. Please, could you clarify
it somehow?
答案1
得分: 2
Sure, here's the translated content:
- 在初始化块内,变量是非静态的。如果它与静态声明没有混合在一起,为什么编译器甚至没有警告我呢?
不,变量仍然是 static
的。你只是给静态变量赋了一个新值。
- 当实例被创建时,strBlock 不再是 null。我无法理解为什么?
实例初始化块被内联到构造函数中,在隐式或显式调用 super(...)
之间以及其余部分之间。你这里的情况等同于:
public class Ex14 {
static String strDef = "在定义的时候";
static String strBlock;
public Ex14() { // 默认构造函数。
super(); // 隐式调用超类构造函数。
// 内联的实例初始化块。
Ex14.strBlock = "在块中";
// 构造函数的其余部分(对于默认构造函数没有)。
}
public static void main (String [] args){
// ...
}
}
因此,在创建实例之前,Ex14.strBlock = "在块中";
这个语句还没有执行,所以它的值是 null
;在创建实例之后(因此执行构造函数),Ex14.strBlock
已经被重新赋值。
英文:
> 1. Inside the initializer block the variable is non-static. If it is not anyhow mixed with that static declaration, why the compiler didn't even warn me?
No, the variable is still static
. You're just assigning a new value to the static variable.
> 2. When an instance was created, strBlock is not null anymore. I can't catch why?
Instance initializers are inlined into the constructor, in between an (implicit or explicit) call to super(...)
and the rest of the body. What you have here is equivalent to:
public class Ex14 {
static String strDef = "At the point of definition";
static String strBlock;
public Ex14() { // Default constructor.
super(); // Implicit super constructor invocation.
// Inlined instance initializer.
Ex14.strBlock = "In a block";
// Rest of the constructor body (there is none for a default ctor).
}
public static void main (String [] args){
// ...
}
}
So, before you create an instance, the Ex14.strBlock = "In a block";
statement hasn't executed, so its value is null
; after you create an instance (and hence execute the constructor), Ex14.strBlock
has been reassigned.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论