为什么在静态init块(继承)之后打印输出

时间:2016-11-08 21:54:01

标签: java inheritance static

问题描述

OCA/OCP Java SE 7 Programmer I & II Study Guide获取的以下代码产生以下输出:

r1 r4 pre b1 b2 r3 r2 hawk

我的解决方案错误pre r1 r4 b1 b2 r3 r2 hawk

这是我遵循的逻辑:

  • 首先,我们首先打印pre实例化<{1}}之前的hawk()

  • static块中的内容将首先打印出来:r1 r4

  • 从基类Bird我们打印块中的内容然后构造函数中的内容:b1, b2
  • 我们转到第一个子类Raptor,然后打印r3, r2
  • 最后,我们打印hawk
  • 中的Hawk
  class Bird {
        {System.out.print("b1 "); }
        public Bird() 
        { 
            System.out.print("b2 ");
        }
    }
    class Raptor extends Bird {
        static { System.out.print("r1 "); }
        public Raptor() 
        { 
            System.out.print("r2 "); 
        }
        { System.out.print("r3 "); }
        static { System.out.print("r4 "); }
    }
    class Hawk extends Raptor {
        public static void main(String[] args) {
            System.out.print("pre ");
            new Hawk();
            System.out.println("hawk ");
        }
    }

本书提供的解决方案的说明

  

静态初始化块在类加载时执行;实例初始化   块在构造函数中调用super()之后立即运行。什么时候   单个类型的多个init块出现在类中,它们运行在   订单,自上而下。

问题

  • 静态初始化块在类加载时执行:这也是Hawk的类加载时间对吗?当加载类hawk时它会自动上传继承树吗?甚至在打印pre之前。
  • 为什么不是解决方案:r1 r4 b1 b2 r3 r2 pre hawk
  • 就像它继承了继承以打印static方法中的内容然后一直向下打印pre。然后它再次向上移动以打印blocksconstructors中的内容。然后终于打印出了鹰。

这对我来说有点困惑。对不起如果我屠杀了java语言。

2 个答案:

答案 0 :(得分:3)

类加载的顺序是:

static initialization blocks
instance initialization blocks
constructor

调用main的{​​{1}}方法时,必须加载其类层次结构。从基类开始,将按顺序调用静态初始化块:

Hawk

第一个r1 r4 被称为

println

该类从下往上初始化。在每个类中,实例初始化块在ctor之前调用。在pre

Bird
b1 b2

中的

Raptor

然后调用最后一个println

r3 r2

答案 1 :(得分:2)

b1 b2 r3 r2不是静态的,所以虽然它们确实是构造实例的一部分,但它们只有在创建后才会被调用(new Hawk();之后出现pre

一般来说,你是正确的,它一直在无用的树上,它是这样做的两次:
- 第一次静止部分
- 构造函数的第二次,通过创建新的Hack触发,因此在pre

之后