Java进行初始化的地方有两个:初始化块和构造函数,其中初始化块又分为静态初始化块和实例初始化块。静态初始化块是类中由static修饰的初始化块,实例初始化块为类中没有任何关键字修饰的初始化语句。
程序在定义一个类的对象之前要先将该类的class文件转载进内存,而class文件是编译后生成的,其中包括了类的初始化过程的定义,即Java 编译器把所有的类变量(静态变量)初始化语句和类型的静态初始化器通通收集到 <clinit> 方法内,该方法只能被 Jvm 调用,专门承担初始化工作。而class文件与类中的成员变量对应的是 "<init>()" 方法。编译器会为每一个构造函数生成一个 "<init>()" 方法。
初始化的时机-------在首次主动使用前初始化
1.创建类的实例
2.访问类或接口的静态变量(static final常量除外,static final变量可以)(此时只会初始化静态变量和静态块,其他在创建该类时初始化)
3.调用类的静态方法
4.反射(Class.forName(packageName.className))
5.初始化类的子类(子类初始化问题:满足主动调用,即访问子类中的静态变量、方法,否则仅父类初始化)
6.java虚拟机启动时被标明为启动类的类
注:加载顺序:启动类的static block最先加载(父类静态成员、静态代码块—>子类静态成员、静态代码块—>父类实例成员、代码块——>父类构造函数—>子类实例成员、代码块—>子类构造函数)
类的静态变量即类变量是在首次装载后完成初始化的,而且此过程只进行一次。而类的成员变量的初始化是在装载完成后创建该类的对象时进行的。由此可知,类的初始化顺序是先静态成员,而后是非静态成员。需要指出的是,不管是静态成员还是非静态成员的初始化,如果存在父类则要先进行父类的初始化,然后才是子类的初始化。初始化块跟定义时初始化是同等的关系,两者的先后顺序与在类中出现的先后有关。当初始化块跟定义时初始化都进行完后则进入构造函数。
静态final变量在编译时不定的情况下。如果客户程序这个时候访问了该类的静态变量,那就会对类进行初始
jvm初始化类时,要求其父类都已经被初始化,但此规则不适用于接口
1.在初始化一个类时,并不会先初始化它所实现的接口
2.在初始化一个接口时,并不会先初始化它的父类接口
程序在定义一个类的对象之前要先将该类的class文件转载进内存,而class文件是编译后生成的,其中包括了类的初始化过程的定义,即Java 编译器把所有的类变量(静态变量)初始化语句和类型的静态初始化器通通收集到 <clinit> 方法内,该方法只能被 Jvm 调用,专门承担初始化工作。而class文件与类中的成员变量对应的是 "<init>()" 方法。编译器会为每一个构造函数生成一个 "<init>()" 方法。
初始化的时机-------在首次主动使用前初始化
1.创建类的实例
2.访问类或接口的静态变量(static final常量除外,static final变量可以)(此时只会初始化静态变量和静态块,其他在创建该类时初始化)
3.调用类的静态方法
4.反射(Class.forName(packageName.className))
5.初始化类的子类(子类初始化问题:满足主动调用,即访问子类中的静态变量、方法,否则仅父类初始化)
6.java虚拟机启动时被标明为启动类的类
注:加载顺序:启动类的static block最先加载(父类静态成员、静态代码块—>子类静态成员、静态代码块—>父类实例成员、代码块——>父类构造函数—>子类实例成员、代码块—>子类构造函数)
类的静态变量即类变量是在首次装载后完成初始化的,而且此过程只进行一次。而类的成员变量的初始化是在装载完成后创建该类的对象时进行的。由此可知,类的初始化顺序是先静态成员,而后是非静态成员。需要指出的是,不管是静态成员还是非静态成员的初始化,如果存在父类则要先进行父类的初始化,然后才是子类的初始化。初始化块跟定义时初始化是同等的关系,两者的先后顺序与在类中出现的先后有关。当初始化块跟定义时初始化都进行完后则进入构造函数。
静态final变量在编译时不定的情况下。如果客户程序这个时候访问了该类的静态变量,那就会对类进行初始
jvm初始化类时,要求其父类都已经被初始化,但此规则不适用于接口
1.在初始化一个类时,并不会先初始化它所实现的接口
2.在初始化一个接口时,并不会先初始化它的父类接口