学了这么久了。回过头来,总结一下Java对象的初始化顺序
java对象在初始化的时候,都涉及到静态变量,静态块,实例变量、实例块和构造方法
代码:
```
class FatherName{ public FatherName(){ System.out.println("父类静态变量"); } } class FuLeiAge{ public FuLeiAge(){ System.out.println("父类实例变量"); } } class FuLei{ protected static FatherName name = new FatherName(); protected FuLeiAge age = new FuLeiAge(); protected FuLei(){ System.out.println("父类构造器"); } static { System.out.println("父类静态块"); } { System.out.println("父类实例块"); } } class SonName{ public SonName(){ System.out.println("子类静态变量"); } } class SonAge{ public SonAge(){ System.out.println("子类实例变量"); } } class ZiLei extends FuLei{ static SonName na = new SonName(); SonAge a = new SonAge(); public ZiLei(){ System.out.println("子类构造器"); } static { System.out.println("子类静态块"); } { System.out.println("子类实例块"); } } public class Test2 { public static void main(String[] args){ System.out.println("main方法开始"); ZiLei ziLei = new ZiLei(); System.out.println("main方法结束"); } }
```
执行结果:
分析:
1、静态变量:由于静态变量为类的所有实例所共享,不依赖于具体的对象,因此不是在对象创建时初始化,而是在类加载时初始化,只执行一次。执行的前后顺序和静态语句块没有绝对的先后顺序,定义在前,就先初始化,定义在后,就在语句块之后执行。
2、静态语句块:在类加载到JVM时执行,由于JVM使用类的前提是类装载到JVM虚拟机,类只加载一次,静态语句块只执行一次。和静态变量的顺序初始化顺序不是绝对的。
3、实例语句块:在构造方法前执行,每调用一次构造方法,执行一次。执行顺序在静态语句块初始化之后,以实例变量初始化为参照,没有绝对的先后顺序,实际顺序取决于定义的顺序,定义在前,就在成员变量初始化前执行;定义在后,就在成员变量初始化后执行。
4、成员变量初始化:在构造方法前执行,每调用一次构造方法,执行一次。执行顺序在静态变量初始化之后,相对于实例语句块的执行顺序取决于定义顺序。
5、构造方法:最后执行。
```
class ZiLei extends FuLei{ public static void main(String[] args){ System.out.println("main方法开始"); ZiLei ziLei = new ZiLei(); System.out.println("main方法结束"); } static { System.out.println("子类静态块"); } static SonName na = new SonName(); SonAge a = new SonAge(); public ZiLei(){ System.out.println("子类构造器"); } { System.out.println("子类实例块"); } }
```
执行结果:
分析:
1、当初始化子类的时候,会先去初始化父类;
2、当main函数在一个类中时,执行的时候,会先去初始化该类的静态变量和静态块,然后再执行面函数,在静态变量和静态块之后。
总结:
1、当一个类要初始化的时候,首先会去执行父类中静态变量和静态块的内容,再去执行本类的静态变量和静态块,然后去执行父类的实例变量、实例块和构造方法,最后执行子类的实例变量、实例块和子类的构造方法;
2、对象初始化的执行顺序为:静态变量>静态块>实例变量>实例块>构造方法,静态变量和静态块的执行顺序不是绝对的,根据定义的前后顺序进行初始化,实例变量和实力块的顺序也不是绝对的,根据定义前后顺序进行初始化;
3、需要注意的是:main函数所在的类,再初始化的时候,会先初始化main函数所在类的静态变量和静态块,然后再去执行main函数;
4、如果有些要求需要在项目启动之前就已经执行,那么就可以将所需要的需求放在静态块中,这种代码是主动执行的,不需要对象或者类的调用就可以执行;
5、有些需求需要项目在启动的时候就初始化,在不创建对象的情况下就可以调用它,就可以使用静态方法,它是被动的。当我们需要用的时候,就可以调用,属于类的属性,静态方法在类加载的时候就已经存在了,如果需要,就可以调用.