直接放结论,变量一定是先声明再赋值,无论是针对普通属性还是静态属性

一个最简单的例子:

1
int i = 1314;

在JVM虚拟机中实现的时候,是先声明变量属性 “i” 的存在,然后为它赋值1314。

我们再来写一个简单的含静态属性的类并声明两个对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class StuDent{
String name;
static int age;

public String getname(){
return this.name;
}
public static void Static(){
System.out.println("一个静态方法");
System.out.println(age);
}
}

StuDent s1 = new StuDent();
StuDent s2 = new StuDent();

其中对象的静态属性的分布在内存中应该是如下图所示:

静态变量是在类初始化时是最先被加载的,JVM会去查找类中所有的静态声明,然后分配空间,这时候只是完成了地址空间的分配,还没有赋值,之后JVM会根据类中静态赋值(包括静态类赋值和静态块赋值)的先后顺序来执行。所以,当一个静态属性的地址被声明之后,它的内存地址的确定的,仅按照最后一次静态代码块的赋值来确定最终赋值。

下面再来举几个比较具体的例子:

1
2
3
4
5
6
7
8
static{
i = 100;
}
public static int i = 1;
public static int m = 200;
static{
m = 100;
}

main函数中输出i和m的值代码结果为1和100。所以我们可以很清晰地看出来,确实是按照最后一次静态代码块的赋值来确定最终值。此外,由于JVM会首先查找类中的所有静态声明,所以即便是在第一个代码块中没有首先声明int变量属性i而是直接赋值,也不会报错,之后才是对它的具体赋值。