类初始化过程
1、一个类要创建实例需要先加载并初始化该类
main方法所在的类需要先加载和初始化
2、一个子类要初始化需要父类初始化
3、一个类初始化就是执行<clinit>()方法
-
- <clinit>()方法由静态变量显示赋值代码和静态代码快组成
- 类变量显示赋值代码和静态代码块从上到下顺序执行
- <clinit>()方法只执行一次
实例初始化过程
1、实例初始化就是执行<linit>()方法
- <linit>()方法可能重载有多个,有多个构造器就有几个<linit>()方法
- <linit>()方法有非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成
- 非静态实例变量显示赋值代码和非静态代码块代码从上到下执行,而对应构造器的代码最后执行
- 每次创建实例对象,调用对应构造器,执行的就是<linit>()方法
- <linit>()方法的首行是super() 或 super(实参列表),即对应父类的<linit>()方法
案例如下:
Father
1 package com.test.entities; 2 3 /** 4 * 父类初始化<clinit>()方法 5 * (1)j = method() 6 * (2)父类的静态代码块 7 * 8 * 父类的实例化方法: 9 * (1)super() (最前) 10 * (2) i = test(); 11 * (3) 父类的非静态代码块 12 * (4) 父类的无参构造(最后) 13 */ 14 public class Father { 15 16 private int i = test(); 17 private static int j = method(); 18 19 static{ 20 System.out.println("(1)"); 21 } 22 Father(){ 23 System.out.println("(2)"); 24 } 25 { 26 System.out.println("(3)"); 27 } 28 29 public int test(){ 30 System.out.println("(4)"); 31 return 1; 32 } 33 public static int method(){ 34 System.out.println("(5)"); 35 return 1; 36 } 37 38 public static void main(String[] args) { 39 // 5 1 4 3 2 40 new Father(); 41 } 42 }
Son
1 package com.test.entities; 2 3 /** 4 * 子类的初始化<clinit>() 5 * (1)j = method() 6 * (2)子类的静态代码块 7 * 8 * 先初始化父类 (5)(1) 9 * 初始化子类 (10)(6 ) 10 * 11 * 子类的实例化方法: 12 * (1)super() (最前) 13 * (2) i = test(); 14 * (3) 子类的非静态代码块 15 * (4) 子类的无参构造(最后) 16 */ 17 public class Son extends Father { 18 private int i = test(); 19 private static int j = method(); 20 static { 21 System.out.println("(6)"); 22 } 23 Son(){ 24 super();//写或不写都存在 25 System.out.println("(7)"); 26 } 27 { 28 System.out.println("(8)"); 29 } 30 public int test(){ 31 System.out.println("(9)"); 32 return 1; 33 } 34 public static int method(){ 35 System.out.println("(10)"); 36 return 1; 37 } 38 39 /** 40 * 类初始化过程 41 * 1 一个类要创建实例需要先加载并初始化该类 42 * main方法所在的类需要先加载和初始化 43 * 2 一个子类要初始化需要父类初始化 44 * 3 一个类初始化就是执行<clinit>()方法 45 * <clinit>()方法由静态变量显示赋值代码和静态代码快组成 46 * 类变量显示赋值代码和静态代码块从上到下顺序执行 47 * <clinit>()方法只执行一次 48 * 49 * 实例初始化过程 50 * 1 实例初始化就是执行<linit>()方法 51 * <linit>()方法可能重载有多个,有多个构造器就有几个<linit>()方法 52 * <linit>()方法有非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成 53 * 非静态实例变量显示赋值代码和非静态代码块代码从上到下执行,而对应构造器的代码最后执行 54 * 每次创建实例对象,调用对应构造器,执行的就是<linit>()方法 55 * <linit>()方法的首行是super() 或 super(实参列表),即对应父类的<linit>()方法 56 * 57 * @param args 58 */ 59 public static void main(String[] args) { 60 // (5)(1)(10)(6) 61 // (9)(3)(2)(9)(8)(7) 62 Son s1 = new Son(); 63 System.out.println("==="); 64 // (9)(3)(2)(9)(8)(7) 65 Son s2 = new Son(); 66 } 67 }