面试题:类的初始化与实例的初始化

代码:

public class Father {
    private int i = test();

    private static int j = method();


    static {
        System.out.print("(1)");
    }

    public Father() {
        System.out.print("(2)");
    }

    {
        System.out.print("(3)");
    }

    public int test() {
        System.out.print("(4)");
        return 1;
    }

    private static int method() {
        System.out.print("(5)");
        return 1;
    }
}

public class Son extends Father {
    private int i = test();

    private static int j = method();


    static {
        System.out.print("(6)");
    }

    public Son() {
        System.out.print("(7)");
    }

    {
        System.out.print("(8)");
    }

    public int test() {
        System.out.print("(9)");
        return 1;
    }

    private static int method() {
        System.out.print("(10)");
        return 1;
    }

    public static void main(String[] args) {
        Son son1 = new Son();
        System.out.println();
        Son son2 = new Son();
    }
}

运行结果:

(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)
(9)(3)(2)(9)(8)(7)

分析:

当运行main方法的时候,首先会初始化类,由于Son是继承Father的,因此会先初始化Father类,然后是Son类

类的初始化

初始化类里面的静态变量、静态代码块,输出:父类(5)(1) 子类(10)(6)

实例的初始化

  • 初始化父类的成员变量、代码块、构造器,输出:(9)(3)(2)

  • 初始化子类的成员变量、代码块、构造器,输出:(9)(8)(7)

问题:

(1) 上面为什么父类的test()方法不会生效呢?

是由于test()被子类重写了,当调用test()的时候,有一个隐式的this()方法,父类调用的其实是子类的test()

(2) 并不是所有的情况下父类方法都会被重写,比如下面几种情况

  • final方法
  • 静态方法
  • private等子类中不可见的方法

(3) 部分执行顺序和位置有关

如果将静态代码块和静态成员变量的位置调换,你会发现结果也会发生变化,同理,将非静态代码块和成员变量的相互调换也会发生变化,会按照从上到下的顺序执行

总结:




猜你喜欢

转载自www.cnblogs.com/songjilong/p/12444456.html