资料-Java基础:父子类加载过程

加载顺序

先上桌结论:

父类静态属性(成员变量) > 父类静态代码块 > 子类静态属性 > 子类静态代码块 > 父类非静态属性 > 父类非静态代码块 > 父类构造器 > 子类非静态属性 > 子类非静态代码块 > 子类构造器

这么长怎么记呀?!

这里帮大家小结几个特点:

  1. 静态属性和代码块,当且仅当该类在程序中第一次被 new 或者第一次被类加载器调用时才会触发(不考虑永久代的回收)。也正是因为上述原因,类优先于对象 加载/new,即 静态优先于非静态。
  2. 属性(成员变量)优先于构造方法,可以这么理解,加载这整个类,需要先知道类具有哪些属性,并且这些属性初始化完毕之后,这个类的对象才算是完整的。另外,非静态代码块其实就是对象 new 的准备工作之一,算是一个不接受任何外来参数的构造方法。因此,属性 > 非静态代码块 > 构造方法。
  3. 有趣的是,静态部分(前4个)是父类 > 子类,而 非静态部分(后6个)也是父类 > 子类。
  4. 另外容易忽略的是,非静态代码块在每次 new 对象时都会运行,可以理解:非静态代码块是正式构造方法前的准备工作(非静态代码块 > 构造方法)。
 1 /**
 2  * @author Lean.Li
 3  * @date 2018/10/15
 4  */
 5 public class Main {
 6 
 7     static class A {
 8         static Hi hi = new Hi("A");
 9 
10         Hi hi2 = new Hi("A2");
11 
12         static {
13             System.out.println("A static");
14         }
15 
16         {
17             System.out.println("AAA");
18         }
19 
20         public A() {
21             System.out.println("A init");
22         }
23     }
24 
25 
26     static class B extends A {
27         static Hi hi = new Hi("B");
28 
29         Hi hi2 = new Hi("B2");
30 
31         static {
32             System.out.println("B static");
33         }
34 
35         {
36             System.out.println("BBB");
37         }
38 
39         public B() {
40             System.out.println("B init");
41         }
42     }
43 
44     static class Hi {
45         public Hi(String str) {
46             System.out.println("Hi " + str);
47         }
48     }
49 
50     public static void main(String[] args) {
51         System.out.println("初次 new B:");
52         B b = new B();
53         System.out.println();
54         System.out.println("第二次 new B:");
55         b = new B();
56     }
57 
58 }

运行结果如下:

初次 new B:
Hi A
A static
Hi B
B static
Hi A2
AAA
A init
Hi B2
BBB
B init

第二次 new B:
Hi A2
AAA
A init
Hi B2
BBB
B init

 

posted @ 2019-09-18 13:53  流浪的蛋炒饭  阅读(289)  评论(0编辑  收藏  举报