目录
名词解释:
单个类中的实例化顺序
父子继承类中实例化顺序
对下述的测试类01,02,03 的输出结果原因是:
对下述的测试类04,05,06 的输出结果原因是:
测试类01:
测试类02:
测试类03:
测试类04:
测试类05
测试类06
静态代码块:就是用static修饰的用{}括起来的代码段,可用于对静态属性进行初始化。类加载时会执行
构造代码块:直接用{}括起来的代码段.对象实例化时候会执行,构造代码块优先于构造函数执行
构造函数:不再赘述
单个类被实例化时候的执行顺序如下:静态代码块 > 构造代码块 > 构造函数。
举例如下.
静态代码块会在类加载时候执行,构造代码块和构造函数会在类实例化时候执行.
可以参考java虚拟机原理 7.2章节的 类加载的时机,现简述如下:
1 遇到new ,getstatic,putstatic,invokestatic ,如果类没有初始化,就要先触发其初始化,
2 如果java.lang.reflect包的方法对类进行反射调用时候,如果类没有进行过初始化,则需要优先触发其初始化
3 如果初始化一个类的时候,其父类还没有初始化,则需要优先触发其父类初始化
4 当虚拟机启动时候,用户需要制定一个要执行的类(包含main()方法的类),虚拟机会优先触发这个主类
5 如果定义一个类的数组,这个类是不会进行初始化的,因为这个数组只有基本的属性,长度等
6 对于静态字段(非静态常量),只有直接定义这个字段的类,才会被初始化.因此,通过其子类来引用父类中定义的静态字段,只会触发父类的初始化,而不会触发子类的初始化.至于是否要触发子类的加载和验证,在虚拟机中没有明确的 规定,这点取决于虚拟机的具体实现.
7 当一个类在初始化时,要求其父类全部已经初始化过了,但是一个接口在初始化时,并不要求其父接口全部都完成了初始化,只有在真正用到父接口时候,才会初始化
测试父类:
public class SupperClass {
public SupperClass(){
System.out.println("父类构造方法");
}
static{
System.out.println("父类静态代码块");
}
{
System.out.println("父类代码块");
}
public static void pll(){
System.out.println("父类静态方法");
}
public static int value = 23;
}
测试子类:
public class SupperClassExtend extends SupperClass {
public SupperClassExtend(){
System.out.println("子类构造方法");
}
static {
System.out.println("子类静态代码块");
}
public static void pl(){
System.out.println("子类静态方法");
}
{
System.out.println("子类代码块");
}
}
public class TestClassLoad {
public static void main(String[] args) {
//实例化子类
SupperClassExtend ex = new SupperClassExtend();
}
}
输出结果为:
父类静态代码块
子类静态代码块
父类代码块
父类构造方法
子类代码块
子类构造方法
输出原因是:
public class TestClassLoad {
public static void main(String[] args) {
//实例化父类
SupperClass ex = new SupperClass();
}
}
输出结果为:
父类静态代码块
父类代码块
父类构造方法
public class TestClassLoad {
public static void main(String[] args) {
//父类的引用指向子类的对象
SupperClass sc = new SupperClassExtend();
}
}
输出结果为:
父类静态代码块
子类静态代码块
父类代码块
父类构造方法
子类代码块
子类构造方法
public class TestClassLoad {
public static void main(String[] args) {
//定义子类或者父类数组(父类数组通子类数组一样,都不会有任何输出)
SupperClassExtend[] ex = new SupperClassExtend[10];
}
}
输出结果为空
public class TestClassLoad {
public static void main(String[] args) {
System.out.println(SupperClassExtend.value);
}
}
输出结果为:
父类静态代码块
23
public class TestClassLoad {
public static void main(String[] args) {
System.out.println(SupperClass.value);
}
}
输出结果为:
父类静态代码块
23