1 题目

 问:main 方法执行后,最终输出的结果。

高频面试题 - 类初始化和实例初始化

1.1 结果 

高频面试题 - 类初始化和实例初始化

2 分析

本题设计三个方面的知识

  1. 类的初始化
    1. 一个类要创建实例,需要先加载并初始化该类
      1. main方法所在的类需要先加载和初始化
    2. 一个子类要初始化,需要先初始化父类
    3. 类的初始化就是执行<clinit>() 方法
      1. <clinit>() 方法由静态类变量显示赋值代码和静态代码块组成
      2. 类变量显示赋值和静态代码块是从上到下执行的
      3. <clinit>() 方法只会执行一次
  2.  实例初始化
    1. 实例初始化就是执行<init>() (构造器)方法
      1. <init>()  方法可能有重载多个,有几个构造器就有几个<init>()  方法
      2. <init>()  方法由非静态实例变量显示赋值代码和非静态代码块、对应的构造器组成
      3. 非静态实例显示赋值代码和非静态代码块是从上到下顺序执行的,构造器最后执行
      4. 每次创建对象,都会调用对应的构造器,执行的就是<init>()方法
      5. <init>() 方法的首行是super,就是对应父类的<init>() 方法
  3. 方法的重写
    1. 哪些方法不可以被重写
      1. final修饰的
      2. 静态方法
      3. private 等子类不可见的方法
    2. 对象的多态性
      1. 子类如果重写了父类的方法,调用子类方法,一定执行的是子类重写过的代码
      2. 非静态方法默认的调用对象是this
      3. this 对象在构造器或者说是<init>()方法 就是正在创建的对象

3 根据上述分析,分析题目

  • 首先是类初始化,先初始化父类,然后执行静态显示赋值语句 j = method() ,
    • 因此输出 (5)
    • 然后执行静态代码块
    • 输出 (1)
    • 然后再初始化子类,同理,输出 (10) (6)
  • 然后实例初始化
    • 先执行父类的<init>方法,执行非静态显示赋值语句, i = test() ,由于i 是非静态方法,因此前面默认是this,此时调用者是子类,因此会执行子类重写的test方法,
    • 输出 (9)
    • 然后再执行父类的非静态代码块
    • 输出(3)
    • 最后执行父类的构造器
    • 输出(2)
    • 然后执行子类中的代码,同理,输出
    • 输出(9)(8)(7)
  • 接下来是第二个创建实例,会再次调用<init>方法,因此(9)(3)(2)(9)(8)(7) 会再次输出

高频面试题 - 类初始化和实例初始化

高频面试题 - 类初始化和实例初始化

 

相关文章: