java 类的初始化顺序
2011-07-07 16:01
106 查看
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点:
运行以上代码,我们会得到如下的输出结果:
1 静态变量
2 静态初始化块
3 变量
4 初始化块
5 构造器
这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:
运行一下上面的代码,结果马上呈现在我们的眼前:
1 父类--静态变量
2 父类--静态初始化块
3 子类--静态变量
4 子类--静态初始化块
5 父类--变量
6 父类--初始化块
7 父类--构造器
8 子类--变量
9 子类--初始化块
10 子类--构造器
现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。
那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。
静态数据的初始化是在类被装载的时候就被初始化,所以在继承中,因为在构造子类之前会先构造父类,这时就会现将父类的class文件加载到jvm中,一旦父类class文件被加载,就会初始化该类中的静态数据(静态变量和静态代码块),父类class文件加载完成接着加载子类的class文件,同理,子类的所有静态数据也被初始化。现在所有的class文件都被加载成功。接着开始初始化对象,从父类开始初始化,为了初始化对象,就要把类中的除静态数据以外的普通变量先初始化,这时普通变量初始化完成,然后是子类的普通变量初始化。再从父类开始,执行父类构造方法,子类构造方法。我发现类的初始化就是按照一个顺序进行:静态数据-->普通变量-->构造函数
。就算是多重继承还是这个顺序,从祖先父类到最下面的子类,先把所有的静态数据初始化。再回过头,从祖先父类到最下面的子类,初始化所有的普通变量。再回过头,从祖先父类到最面的子类,初始化构造器。
public class InitialOrderTest { //静态变量 public static String staticField = "静态变量"; //变量 public String field = "变量"; //静态初始化块 static { System.out.println(staticField); System.out.println("静态初始化块"); } //初始化块 { System.out.println(field); System.out.println("初始化块"); } //构造器 public InitialOrderTest() { System.out.println("构造器"); } public static void main(String[] args) { new InitialOrderTest(); } } |
1 静态变量
2 静态初始化块
3 变量
4 初始化块
5 构造器
这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:
class Parent { //静态变量 public static String p_StaticField = "父类--静态变量"; //变量 public String p_Field = "父类--变量"; //静态初始化块 static { System.out.println(p_StaticField); System.out.println("父类--静态初始化块"); } //初始化块 { System.out.println(p_Field); System.out.println("父类--初始化块"); } //构造器 public Parent() { System.out.println("父类--构造器"); } } public class SubClass extends Parent { //静态变量 public static String s_StaticField = "子类--静态变量"; //变量 public String s_Field = "子类--变量"; //静态初始化块 static { System.out.println(s_StaticField); System.out.println("子类--静态初始化块"); } //初始化块 { System.out.println(s_Field); System.out.println("子类--初始化块"); } //构造器 public SubClass() { System.out.println("子类--构造器"); } //程序入口 public static void main(String[] args) { new SubClass(); } } |
1 父类--静态变量
2 父类--静态初始化块
3 子类--静态变量
4 子类--静态初始化块
5 父类--变量
6 父类--初始化块
7 父类--构造器
8 子类--变量
9 子类--初始化块
10 子类--构造器
现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。
那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。
静态数据的初始化是在类被装载的时候就被初始化,所以在继承中,因为在构造子类之前会先构造父类,这时就会现将父类的class文件加载到jvm中,一旦父类class文件被加载,就会初始化该类中的静态数据(静态变量和静态代码块),父类class文件加载完成接着加载子类的class文件,同理,子类的所有静态数据也被初始化。现在所有的class文件都被加载成功。接着开始初始化对象,从父类开始初始化,为了初始化对象,就要把类中的除静态数据以外的普通变量先初始化,这时普通变量初始化完成,然后是子类的普通变量初始化。再从父类开始,执行父类构造方法,子类构造方法。我发现类的初始化就是按照一个顺序进行:静态数据-->普通变量-->构造函数
。就算是多重继承还是这个顺序,从祖先父类到最下面的子类,先把所有的静态数据初始化。再回过头,从祖先父类到最下面的子类,初始化所有的普通变量。再回过头,从祖先父类到最面的子类,初始化构造器。
相关文章推荐
- JAVA初始化顺序
- Java基础5----初始化顺序
- java类成员初始化顺序
- java初始化顺序
- Java基础巩固:类和对象的初始化顺序
- java基础---静态变量,成员变量,局部变量及类的初始化顺序
- java中初始化顺序
- JAVA的初始化顺序
- Java类初始化顺序
- java 初始化的加载顺序问题
- java程序在执行过程中,类,对象以及它们成员加载、初始化的顺序如下:
- java 类初始化顺序
- java中的初始化顺序
- java类的加载以及初始化顺序
- Java――对象初始化顺序使用详解
- Java初始化顺序
- java初始化顺序
- java中static变量与非static变量初始化顺序
- java对象初始化的先后顺序
- java基础知识之Java程序初始化顺序