在Java中,变量的初始化顺序是:静态变量&静态代码块 》变量&普通代码块 》构造器。之前的一个误区是构造器的执行顺序是仅次于静态变量和静态得代码块的。换个角度想一下,其实很好理解为什么构造器要在最后在执行。因为,假设构造器中需要一个变量,若变量在构造器之后初始化,这就会造成变量未初始化就调用的现象,显然这在任何编程语言中是不允许的(虽然很多语言都有默认的初始值)。下面举一个简单的例子:
public class ParamerInit {
{
System.out.println("普通代码块");
}
static
{
System.out.println("静态代码块");
}
public ParamerInit(){
System.out.println("构造器");
}
public BaseClasss class_1=new BaseClasss("普通变量");
public static BaseClasss class_2=new BaseClasss("静态变量");
public static void main(String[] args) {
new ParamerInit();
}
}
//执行结果
静态代码块
静态变量
普通代码块
普通变量
构造器
需要注意的是静态变量和静态代码块以及普通变量和普通代码块之间的顺序又是怎么样的呢?答案是:和其定义的顺序有关,看如下代码以及执行结果。
public class ParamerInit {
public BaseClasss class_1=new BaseClasss("普通变量");
public static BaseClasss class_2=new BaseClasss("静态变量");
{
System.out.println("普通代码块");
}
static
{
System.out.println("静态代码块");
}
public ParamerInit(){
System.out.println("构造器");
}
public static void main(String[] args) {
new ParamerInit();
}
}
//执行结果
静态变量
静态代码块
普通变量
普通代码块
构造器
当我把静态变量和静态代码块以及变量和普通代码块的定义顺序对调之后,得到的结果如上,这说明对于静态的变量和代码块来说,它们之间的执顺序根据其定义顺序而定,同样对于普通变量和代码块来说亦然。
上述结果都是没有继承类,仅在单一类中的变量执行顺序,那么如果有继承类时,子类和父类当中变量执行顺序又是怎样的?
//该类继承自上述父类
public class ExtendsClassInit extends ParamerInit{
{
System.out.println("子类---普通代码块");
}
static
{
System.out.println("子类---静态代码块");
}
public ExtendsClassInit(){
System.out.println("子类---构造器");
}
public BaseClasss class_1=new BaseClasss("子类---普通变量");
public static BaseClasss class_2=new BaseClasss("子类---静态变量");
public static void main(String[] args) {
new ExtendsClassInit();
}
}
//执行结果
父类---静态变量
父类---静态代码块
子类---静态代码块
子类---静态变量
父类---普通变量
父类---普通代码块
父类---构造器
子类---普通代码块
子类---普通变量
子类---构造器
从结果很容易的看到,对于有继承类的变量的初始化顺序是首先初始化父类当中的静态变量和代码块,其次是子类当中的静态变量和代码块,然后继续初始化父类中的普通变量和代码块,最后是子类中的普通变量和代码块。即优先初始化的是父类中的变量。