类初始化 (static部分)
执行clinit方法
- main方法 所在的类需要 先加载和初始化
- 子类的初始化需要先初始化父类
- 类初始化就是指向<clinit>()方法
①、<clinit>()方法由静态 类变量显示赋值代码 和 静态代码块 组成
②、类变量显示赋值代码 和 静态代码块代码 从上到下 循序执行(<cliinit>()方法内顺序执行)
③、<clinit>()方法 只执行一次
实例初始化 (非static部分)
实例初始化会执行<init>方法(上面是clinit即类的初始化)
- <init>()方法可能重载有多个,有几个构造器就有几个<init>方法
- <init>()方法由非静态实例变量显示赋值代码块和非静态代码块、对应构造器代码组成
- 非静态实例变量显示赋值代码和非静态代码块代码从上到下顺序执行,对应构造器代码最后执行
- 每次创建实例对象,调用对应构造器,执行的就是对应的<init>()方法
- <init>()方法的首行是super()或super(实参参数列表)对应父类的<init>()方法
字节码文件示例:
例题分析:
执行下面的Son类中的main方法会输出什么?
Father.java文件
public class Father{ private int i = test(); private static int j = method(); static{ System.out.print("(1)"); } Father(){ System.out.print("(2)"); } { System.out.print("(3)"); } public int test(){ System.out.print("(4)"); return 1; } public static int method(){ System.out.print("(5)"); return 1; } }
Son.java文件 执行下面的代码会输出什么?
public class Son extends Father{ private int i = test(); private static int j = method(); static{ System.out.print("(6)"); } Son(){ // super();//写或不写都在,在子类构造器中一定会调用父类的构造器 System.out.print("(7)"); } { System.out.print("(8)"); } public int test(){ System.out.print("(9)"); return 1; } public static int method(){ System.out.print("(10)"); return 1; } public static void main(String[] args) { // Son s1 = new Son(); // System.out.println(); // Son s2 = new Son(); } }
结果