类的初始化和实例初始化

    技术2022-07-10  151

    这里的原理和例子来源自尚硅谷的讲师宋红康(深入理解JVM)和柴林燕(Java面试题),表示非常感谢。 java程序将字节码通过类的加载子系统将类的元信息加载到方法区中,一共有三步,加载,链接,初始化。具体请看深入理解JVM。这里通过题目演示类的初始化和实例初始化。 father类

    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类

    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类,输出的结果为 这是为什么呢,主方法里面并没有调用任何函数?这就需要讲解一下类的初始化过程了。 类的初始化过程 所以当运行主方法时,将son和father类加载进虚拟机的方法区。main方法在son类中,要加载son类的时候需要先加载其父类father,而在初始化son的时候需要先初始化father,在初始化father时,执行方法,赋值静态的类变量的静态代码块。所以就先输出(5)(1),接下里初始化son类,也是赋值静态的类变量的静态代码块。所以输出(10)(6)。

    实例的初始化过程 在上面代码的基础上,修改main方法,加上一下三行代码

    Son s1 = new Son(); System.out.println(); Son s2 = new Son();

    则输出结果为 其中(5)(1)(10)(6)上面为两个类初始化的输出结果,主要讨论后面的输出结果,这就涉及到实例的初始化和方法的重写了。 分析结果:我们从上知道,实例化对象就是调用方法,也就是构造器,**注意:每个构造器不管你加不加都默认有一句super();**也即是说先需要调用父类的构造器。然后在初始化非静态变量和非静态代码块,最后再执行构造器。所以过程如下 son类

    * 子类的实例化方法<init>*1super()(最前) (9)(3)(2*2)i = test();9*3)子类的非静态代码块 (8*4)子类的无参构造(最后) (7

    father类

    * 父类的实例化方法: *1super()(最前) *2)i = test(); *3)父类的非静态代码块 *4)父类的无参构造(最后) * * 非静态方法前面其实有一个默认的对象this * this在构造器(或<init>)它表示的是正在创建的对象,因为这里是在创建Son对象,所以 * test()执行的是子类重写的代码(面向对象多态) * * 这里i=test()执行的是子类重写的test()方法 *

    根据这个分析可以得出结果。

    Processed: 0.011, SQL: 9