对于一般的Java类加载顺序是这样的
2. 自身的静态变量赋值
3. 父类成员变量赋值和父类块赋值
4. 父类构造函数赋值
5. 自身成员变量赋值和自身块赋值
6. 自身构造函数赋值
但是最近看到了一道题目
package com.test;
public class StaticTest {
public static void main(String[] args)
{
staticFunction();
}
static StaticTest st = new StaticTest();
static
{
System.out.println("1");
}
{
System.out.println("2");
}
StaticTest()
{
System.out.println("3");
System.out.println("a="+a+",b="+b);
}
public static void staticFunction(){
System.out.println("4");
}
int a=110;
static int b =112;
}
根据上面的代码,有以下步骤:
- 首先在执行此段代码时,首先由main方法的调用触发静态初始化。
- 在初始化Test 类的静态部分时,遇到st这个成员。
- 但凑巧这个变量引用的是本类的实例。
- 那么问题来了,此时静态初始化过程还没完成就要初始化实例部分了。是这样么?
- 从人的角度是的。但从java的角度,一旦开始初始化静态部分,无论是否完成,后续都不会再重新触发静态初始化流程了。
- 因此在实例化st变量时,实际上是把实例初始化嵌入到了静态初始化流程中,并且在楼主的问题中,嵌入到了静态初始化的起始位置。这就导致了实例初始化完全至于静态初始化之前。这也是导致a有值b没值的原因。
- 最后再考虑到文本顺序,结果就显而易见了。