Java类中各部分的加载顺序

原创 2018年04月17日 20:46:09

直接上例子来说明比较直观.

准备工作:

Class A:

package com.ld.test;

/**
 * Created by 123 on 2018/4/13.
 */
public class A {
    private static String a_mark1 = initA_Mark1();
    private String a_mark2;

    static {
        System.out.println("This is static code block of A.");
        System.out.println(a_mark1);
    }

    {
        System.out.println("This is code block of A.");

        if(a_mark2 == null) {
            System.out.println("a_mark2 is null");
        } else {
            System.out.println(a_mark2);
        }
    }

    public A() {
        System.out.println("This is default constructor of A.");

        a_mark2 = "a_mark2";

        System.out.println(a_mark2);
    }

    private static String initA_Mark1() {
        System.out.println("This is static initialized method of A.");
        return "a_mark1";
    }
}

Class B:

package com.ld.test;

/**
 * Created by 123 on 2018/4/13.
 */
public class B extends A {
    private static String b_mark3 = initb_mark3();
    private String b_mark4;

    static {
        System.out.println("This is static code block of B.");
        System.out.println(b_mark3);
    }

    {
        System.out.println("This is code block of B.");

        if(b_mark4 == null) {
            System.out.println("b_mark4 is null");
        } else {
            System.out.println(b_mark4);
        }
    }

    public B() {
        System.out.println("This is default constructor of B.");
    }

    public B(String b_mark4) {
        this();

        System.out.println("This is custom constructor of B.");

        this.b_mark4 = b_mark4;

        System.out.println(b_mark4);
    }

    private static String initb_mark3() {
        System.out.println("This is static initialized method of B.");
        return "b_mark3";
    }

    public static void main(String[] args) {
        System.out.println("Execute main method.");
        B b = new B("b_mark4");
        System.out.println("Initialization end.");
    }
}

*说明:  A,B两类在同一包下(com.ld.test), B继承自A.

---------------------------------------------------------------------------------------------------
执行B类的main方法....
---------------------------------------------------------------------------------------------------

执行结果:
This is static initialized method of A.
This is static code block of A.
a_mark1
This is static initialized method of B.
This is static code block of B.
b_mark3
Execute main method.
This is code block of A.
a_mark2 is null
This is default constructor of A.
a_mark2
This is code block of B.
b_mark4 is null
This is default constructor of B.
This is custom constructor of B.
b_mark4
Initialization end.


解释:

稍微了解java的同学都知道, 类是在jvm启动后才会加载. 但有想过是在什么时候加载吗?  根据上面的例子不难看出, 一定是在使用这个类的静态资源或者创建这个类的对象的时候才会加载, 本例中属于在使用类的静态资源的时候加载.  别忘了,B类中的main方法也是静态的, 它也属于类的静态资源, 所以当执行main方法时类就被加载了.

1. 首先肯定要先加载静态资源, 而B又继承自A, 所以先加载A类中的静态成员和静态代码块, 所以先执行initA_Mark1()方法,输出"This is static initialized method of A.", 并将a_mark1的值初始化为"a_mark1".


2. A类中的静态成员初始化完成后, 紧接着就该执行A类的静态代码块, 所以输出"This is static code block of A.", 并打印a_mark1的值"a_mark1".

3. A类中的静态成员和静态代码块执行完后, 就轮到子类B了, 所以执行B类中的initB_mark3()方法, 输出"This is static initialized method of B.", 并将b_mark3的值初始化为b_mark3.

4. 接着是B类中的静态代码块, 输出"This is static code block of B.", 打印b_mark3值"b_mark3".

5. 现在A, B两个类的静态部分都加载完成, 所以执行main方法中的第一行代码, 输出"Execute main method."

6. 接着执行第二行代码"B b = new B("b_mark4");", 因为这里创建了一个B的对象, 而B又继承自A, 所以会先创建一个A的对象.

7. A类中非静态的代码块会首先执行, 非静态代码块的作用就是在构造方法之前做一些额外的初始化操作.  现在执行A类中的代码块,输出"This is code block of A.", 并判断成员变量a_mark2的值是否为空, 若为空则输出提示语:"a_mark2 is null", 不为空则输出a_mark2的值.  因为a_mark2还未被初始化, 所以jvm默认赋给它一个null, 所以会输出提示语:"a_mark2 is null".

8. 代码块执行完后, 为了确保A类对象创建成功(对象完成初始化), jvm会调用A类的默认构造方法, 所以输出"This is default constructor of A.", 并将成员a_mark2的值赋为"a_mark2", 随后打印a_mark2值, 输出"a_mark2". 至此, A类的对象完成创建.

9. B类对象的创建与上述流程一样, 也是先执行代码块,输出"This is code block of B.",  对B类中成员变量b_mark4进行非空判断, 同上, 所以输出"b_mark4 is null".

10. 因为在创建B对象的时候传入了参数, 所以会调用B类中的有参构造方法.

11. 在该构造方法中, 可以看到执行了"this();", 这句代码会调用B类的默认构造方法(这句代码必须写在第一句), 所以会先输出"This is default constructor of B.", 然后回到有参构造方法中,输出"This is custom constructor of B.", 将成员变量b_mark4的值初始化为创建B对象时传入的参数, 再输出b_mark4值"b_mark4", 至此,完成了B对象的创建.

12. 执行main方法中的最后一句代码, 输出"Initialization end.", 完成整个类的加载和对象的创建. 



总结:

* 类中静态资源首次加载的时间是类中静态资源第一次被调用的时候或者该类的对象第一次被创建的时候

* 类按照  静态成员 --> 静态代码块 --> 普通成员 --> 代码块 --> 构造方法 的顺序来加载.
 
* 在创建一个类的对象时, 如果该类有父类, 则先执行父类对象的创建, 各部分加载的顺序也是按上述顺序加载

* 别忘了main方法也属于类的静态资源.

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wn084/article/details/79969603

Java类中的各种成员的加载顺序

源代码: public class SuperAndSub { public static void main(String[] args) { // Super s1 = new...
  • u014738304
  • u014738304
  • 2016-09-19 22:27:49
  • 2100

关于类加载到执行过程中各个部分的执行顺序

单个类的情况:先上代码public class Ext { static{ System.out.println("我是静态代码块1~"); } { ...
  • u013592371
  • u013592371
  • 2016-12-21 23:03:31
  • 163

类加载时类各部分的加载顺序

public class TestStatic9{ public static void main(String[] args){ B bb = new B(); } } class...
  • qq_36636154
  • qq_36636154
  • 2018-02-07 20:22:56
  • 17

java中类的加载顺序介绍(ClassLoader)

1、ClassNotFoundExcetpion 我们在开发中,经常可以遇见java.lang.ClassNotFoundExcetpion这个异常,今天我就来总结一下这个问题。对于这个异常,它实质...
  • eff666
  • eff666
  • 2016-08-14 10:44:15
  • 22502

Java中类及方法的加载顺序

1. 虚拟机在首次加载Java类时,会对静态代码块、静态成员变量、静态方法进行一次初始化(静态间按顺序执行)。 2. 只有在调用new方法时才会创建类的实例。 3. 类实例创建过程:父子继承关系,先父...
  • hellorichen
  • hellorichen
  • 2016-11-02 15:32:47
  • 5501

java中变量加载顺序再学习

先看一段代码: public class HelloB extends HelloA{ public HelloB(){ System.out.println("HelloB"); } ...
  • anLA_
  • anLA_
  • 2017-03-12 13:03:00
  • 918

关于类、方法、变量、语句块的加载顺序

public static String strA = "③、静态语句块只加载一次"; public static void main(String[] args) { System.out.p...
  • lidachao01
  • lidachao01
  • 2015-08-28 17:52:06
  • 860

JAVA类在初始化时成员的加载顺序

JAVA类在初始化时成员的加载顺序 基础知识铺垫 代码块1-1 初始化类时的代码加载顺序 调用静态函数时代码加载顺序JAVA类在初始化时成员的加载顺序基础知识铺垫:java语言支持四中类型:接口、类、...
  • u014665036
  • u014665036
  • 2015-05-22 12:16:19
  • 182

Java类中各模块的加载顺序的JVM本质理解

Java类中各模块的加载顺序只是表象,但至于为什么我们需要理解JVM的加载本质原理。...
  • wzw9353
  • wzw9353
  • 2017-07-09 16:15:26
  • 766

Java中类加载的执行顺序

一、Java中的类加载demo顶层基类Base.java:public class Base { public static int a = 10; public int b = 20...
  • isee361820238
  • isee361820238
  • 2016-09-29 16:46:36
  • 2339
收藏助手
不良信息举报
您举报文章:Java类中各部分的加载顺序
举报原因:
原因补充:

(最多只允许输入30个字)