【面试题】Java类的初始化和实例化等重要考点

前言:

本文通过引用一道经典的Java面试题,解释Java类、实例对象的初始化和实例化等知识。主要内容有以下三点:

1.类初始化过程(先)

2.实例初始化过程(后)

3.方法重写(注意)

首先看题目,分析输出结果是什么:

父类: 

public class Father {
    private int i = test();
    private static int j = method();
    static {
        System.out.println("(1)");
    }
    Father() {
        System.out.println("(2)");
    }

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

    public int test() {
        System.out.println("(4)");
        return 1;
    }
    public static int method() {
        System.out.println("(5)");
        return 1;
    }
}

子类: 

public class Son extends Father {
    private int i = test();
    private static int j = method();
    static {
        System.out.println("(6)");
    }
    Son() {
        System.out.println("(7)");
    }
    {
        System.out.println("(8)");
    }
    public int test() {
        System.out.println("(9)");
        return 1;
    }

    public static int method() {
        System.out.println("(10)");
        return 1;
    }
    //TEST
    public static void main(String[] args) {
        Son son  = new Son();
        System.out.println();
        Son son1 = new Son();
    }

}

 1.类初始化过程

(1)主方法main所在的类要先加载初始化(即使main中没有内容)

(2)创建实例对象的时候会先加载初始化类

(3)一个子类初始化需要先初始化它的父类 

(4)类初始化其实就是执行<clinit>()方法,它由静态类变量静态代码块组成,执行顺序从上到下。

      综上,首先主方法main()所在的类先加载初始化(1),而加载这个子类前要先加载初始化其父类(3),也即是Father的静态类变量j=method()【输出1】,静态代码块【输出5】,从上到下执行;父类加载完成后开始加载Son的静态类变量j=method()【输出10】,静态代码块【输出6】,从上到下执行(4)。

2.实例初始化过程

(1)实例初始化实际就是执行<init>()方法,<clinit>一个类只有一个,但是<init>有多少个构造器就有多少个(可能有带参、不带参多个构造器)。它由静态类变量静态代码块构造器三部分组成其中,非静态实例变量和非静态代码块执行顺序从上到下,构造器最后执行。

(2)<init>()方法首行都是super(),不管写没写,它都是存在的。

综上,子类实例化方法分为以下四步:

  • 1、super()  => 父类的实例化(又是这三步)
  • 2、子类非静态实例变量,非静态代码块执行顺序从上到下
  • 3、子类构造器

1、首先是super(),父类实例化,非静态变量i=test,但是这里涉及到方法重写,非静态方法前的默认的调用对象是this,而this指的是正在创建的对象,也就是子类对象,所以i=test输出的是子类中的test方法:【输出9】;其次是父类非静态代码块:【输出3】,然后是父类构造器最后:【输出2】

扫描二维码关注公众号,回复: 10716605 查看本文章

2、子类的非静态变量i=test方法:【输出9】;子类非静态代码块:【输出8】;从上到下顺序执行

3、子类构造器最后:【输出7】

第二个Son对象创建,又重新一次,输出【932987】,所以总的输出位【1 5 10 6 9 3 2 9 8 7 9 3 2 9 8 7】

3.关于方法重写

如果子类重写了父类的方法,通过子类对象调用的就一定是子类重写过的代码,可能会疑问,为什么方法test()被子类重写,而method方法不会被重写呢,那么什么方法不可以被重写

(1)final方法不可以被重写

(2)静态方法不能被重写

(3)private等子类中不可见的方法不可被重写

发布了20 篇原创文章 · 获赞 15 · 访问量 216

猜你喜欢

转载自blog.csdn.net/qq_37414463/article/details/105460340