Java面试基础篇——第五篇:类的实例化顺序

类的实例化顺序:包括 1.父类静态数据,构造函数,字段;2.子类静态数据,构造函数,字段等, 当咱们new一个对象的时候,类实例化的顺序是怎么样的呢?java

OK.仍是上代码比较实在(我就是个实在的人~~ 哈哈)app

咱们先新建一个父类,里面包括静态数据,构造函数,字段,方法等...ide

/**
 * @author Lee
 * @// TODO 2018/7/18-13:13
 * @description
 */
public class FatherClazz {
    int one = 1;

    int two = getTwo();

    // 静态代码块
    static {
        System.out.println("父类静态代码块被实例化了...");
    }


    {
        int three = 3;
        System.out.println("FatherOne:" + one + "," + "FatherTwo:" + two + "," + "FatherThree" + three);
    }

    // 构造函数
    public FatherClazz() {
        this(4);
        System.out.println("父类无参构造函数...");
    }

    public FatherClazz(int num) {
        System.out.println("父类带参数的构造函数..." + num);
    }

    int getTwo() {
        System.out.println("父类getTwo方法...");
        return 2;
    }

    public void methodFirst() {
        System.out.println("Hi,我是methodFirst...");
    }

}

新建一个ChildClazz继承FatherClazz~函数

/**
 * @author Lee
 * @// TODO 2018/7/18-13:24
 * @description
 */
public class ChildClazz extends FatherClazz {
    int childOne = 11;
    int childTwo = getChildTwo();

    {
        int childThree = 33;
        System.out.println("childOne:" +childOne +"," + "childTwo: " +childTwo + "," + "childThree:" +childThree);
    }

    public ChildClazz(){
        this(88);
        System.out.println("childClazz's construct function!");
    }

    public ChildClazz(int num) {
        System.out.println("childClazz's construct function with variable : " + num);
    }

    {
        System.out.println("childClazz is starting...");
    }

    public int getChildTwo() {
        System.out.println("Hi, I'm childClazz's getTwo method ...");
        return 22;
    }

    static {
        System.out.println("childClazz static code is running ...");
    }

    @Override
    public void methodFirst() {
        System.out.println("method is childClazz");
        super.methodFirst();
    }
}

好了,还剩一步,来写一个main方法测试下测试

/**
 * @author Lee
 * @// TODO 2018/7/18-13:33
 * @description 测试类的实例化顺序
 */
public class NewClazz {
    public static void main(String[] args) {
        System.out.println("main app is running ");
        ChildClazz childClazz = new ChildClazz();
        childClazz.methodFirst();
    }
}

走你~~ (因为截图不大美观,我这就复制控制台的输出信息了···)this

main app is running 
父类静态代码块被实例化了...
childClazz static code is running ...
父类getTwo方法...
FatherOne:1,FatherTwo:2,FatherThree3
父类带参数的构造函数...4
父类无参构造函数...
Hi, I'm childClazz's getTwo method ...
childOne:11,childTwo: 22,childThree:33
childClazz is starting...
childClazz's construct function with variable : 88
childClazz's construct function!
method is childClazz
Hi,我是methodFirst...

OK,来分析下程序输出的结果: 1,首先会执行类中static代码块(无论代码块是否在类的开头仍是末尾处),若是这个类有父类,一样会优先查找父类中的static代码块,而后执行当前类的static。code

2,而后从父类的第一行开始执行,直至代码末尾处,中间无论是有赋值仍是method调用,都会按顺序一一执行(method),普通代码块{ }...对象

3,其次是父类的构造函数,执行带参数或不带参数的构造函数,依赖于实例化的类的构造函数有没有super父类的带参或不带参的构造函数(能够把上述ChildClazz构造方法中的this(88)替换成super(88)来测试)。继承

4,而后会从子类(当前类)的第一行开始执行,直至代码末尾处,中间无论是有赋值仍是method调用,都会按顺序一一执行(method),普通代码块{ }...three

5,接着会是子类(当前类)的构造函数,按顺序执行。

6,最后是类方法的调用执行,若是子类覆盖了父类的method,执行时会先执行子类覆盖的method,method内若是有super.method(),才会调用父类的同名method,不然不会。

别人总结的:先静态、先父后子。 先静态:父静态 > 子静态 。优先级:父类 > 子类 , 静态代码块 > 非静态代码块 > 构造函数。

相关文章
相关标签/搜索