我使用的是同样的概念,我在头等舱使用过。
b被初始化为0,我用b时到处都是0。
经过一段时间后我得到了原因并运行了调试器,看到一个函数调用之前没有分配任何值。变量a只有值默认值0。
但是当我运行类Test2时。它给出了输出5.
我想知道这个初始化何时发生? 我知道静态变量在编译时获得值。但静态决赛怎么样? 当这个变量得到它的值时?
public class Test1 {
static int b=add();
static int add()
{
return a;
}
static int a=5;
public static void main(String[] args) {
System.out.println(b);
}
}
//Gives output 0
public class Test2 {
static int b=add();
static int add()
{
return a;
}
final static int a=5;
public static void main(String[] args) {
System.out.println(b);
}
}
//gives output 5
答案 0 :(得分:4)
从Java语言规范的12.4.2部分开始,初始化Class的过程如下:
- 然后,初始化最终的类变量和接口的字段,其值是编译时常量表达式(§8.3.2.1,§9.3.1, §13.4.9,§15.28)。
- 接下来,执行类的类变量初始值设定项和静态初始化程序,或者执行该字段的字段初始值设定项 界面,按文字顺序,好像它们是一个单独的块。
因此,最终变量将在静态变量之前初始化。你会得到输出5
。
答案 1 :(得分:3)
原始和final static
类型的String
字段由java编译器专门处理:它们是编译时常量。它们的值只是内联到它使用的代码中。我们来看看生成的字节码。
Test1
上课:
static int add();
Code:
0: getstatic #17 // Field a:I
3: ireturn
所以它确实加载了一个静态字段。
Test2
上课:
static int add();
Code:
0: iconst_5
1: ireturn
这里只推送预定义的常量值5
,甚至不引用常量字段。
答案 2 :(得分:0)
只是为了添加其他答案:
在您a
不是最终的第一种情况下,b
的值在a
之前分配,这就是您获得0的原因。分配的顺序由序列决定的陈述。如果您在static int a=5;
的分配声明之前移动b
,则会获得5。