Java 类中类属性 (static 变量) 和对象属性 (非 static 变量) 的初始化顺序可以用如下程序测试
/**
* @(#) Testjava
* @author fancy
*/
public class Test {
static String a = stringa;
static String b;
String c = stirngc;
String d;
static {
printStatic(before static);
b = stringb;
printStatic(after static);
}
public static void printStatic(String title) {
Systemoutprintln( + title + );
Systemoutprintln(a = \ + a + \);
Systemoutprintln(b = \ + b + \);
}
public Test() {
print(before constructor);
d = stringd;
print(after constructor);
}
public void print(String title) {
Systemoutprintln( + title + );
Systemoutprintln(a = \ + a + \);
Systemoutprintln(b = \ + b + \);
Systemoutprintln(c = \ + c + \);
Systemoutprintln(d = \ + d + \);
}
public static void main(String[] args) {
new Test();
}
}
首先我把 main() 方法注释掉运行结果如下
before static
a = stringa
b = null
after static
a = stringa
b = stringb
javalangNoSuchMethodError: main
Exception in thread main
Process completed
然后取消对 main() 方法的注释运行结果如下
before static
a = stringa
b = null
after static
a = stringa
b = stringb
before constructor
a = stringa
b = stringb
c = stirngc
d = null
after constructor
a = stringa
b = stringb
c = stirngc
d = stringd
由此可以看出 Java 类属性和对象属性的初始化顺序如下
① 类属性 (静态变量) 定义时的初始化如上例的 static String a = stringa;
② static 块中的初始化代码如上例 static {} 中的 b = stringb;
③ 对象属性 (非静态变量) 定义时的初始化如上例的 String c = stirngc;
④ 构造方法 (函数) 中的初始化代码如上例构造方法中的 d = stringd;
在此过程中 ② 和 ③ 的顺序无所确定因为在静态块中无法打印出非静态变量同样是因为这个原因知道他们的顺序对我们写程序也毫无帮助再因为类成员 (静态成员) 是在第一次使用到类的时候就进行了相应的初始化而对象成员 (非静态成员) 则需要生成类实例 (即对象) 时才能初始化所以我把 ③ 排在了 ② 的后面再申明一次它们究竟谁先谁后从代码上是不能确定的恐怕需要去研究一下 JVM (Java 虚拟机) 的执行过程才行
以下是一些回帖的讨论
我对狂人教程对象成员 (非静态成员) 则需要生成类实例 (即对象) 时才能初始化有些看法!例如你在例程中定义的两个对象成员变量String c = stirngc;
String d;我认为当程序执行这个Test类的时候成员变量(不包括构造函数)和类成员变量一样都要装载到内存这样对象成员变量就可以被构造函数所调用但是究竟静态变量和非静态变量哪个先执行可以看在代码中的先后顺序但是这对于编写代码来说并没有多大的用处!
static
{
printStatic(before static);
b = stringb;
printStatic(after static);
}在类别第一次使用而载入时执行且只执行一次
caterpillar