美文网首页
Java类的初始化顺序

Java类的初始化顺序

作者: 程序员汪汪 | 来源:发表于2021-02-14 23:00 被阅读0次

本文主要演示Java类的初始化顺序,分为有继承和没有继承两种情况。如有错误,劳烦指正,不胜感谢!

没有继承情况

直接上代码,工具类:

/**
 * 工具类Log
 */
public class Log {

    public static String baseFieldInit() {
        System.out.println("父类普通成员变量");
        return "";
    }

    public static String baseStaticFieldInit() {
        System.out.println("父类静态成员变量");
        return "";
    }

    public static String fieldInit() {
        System.out.println("子类普通成员变量");
        return "";
    }

    public static String staticFieldInit() {
        System.out.println("子类静态成员变量");
        return "";
    }
}

父类:

/**
 * 父类/基类 为了方便后面有继承的情况,所以这里直接使用父类
 */
public class Base {

    static {
        System.out.println("父类静态代码块 1");
    }

    private static String staticValue = Log.baseStaticFieldInit();

    static {
        System.out.println("父类静态代码块 2");
    }

    {
        System.out.println("父类构造代码块 1");
    }

    private String value = Log.baseFieldInit();

    {
        System.out.println("父类构造代码块 2");
    }

    Base() {
        System.out.println("父类构造方法");
    }

    public static void main(String[] args) {
        //在 new 对象之前打印输出只是为了证明main方法虽然是程序入口,但是并不会最先执行
        System.out.println("new 之前");
        new Base();
        System.out.println("new 之后");
    }

}

输出:

父类静态代码块 1
父类静态成员变量
父类静态代码块 2
new 之前
父类构造代码块 1
父类普通成员变量
父类构造代码块 2
父类构造方法
new 之后

结论:

  1. 静态代码块和静态成员变量并列优先级,按代码中出现的先后顺序执行,只有在第一次加载类时执行。
  2. 在执行完静态代码块之后,会执行main方法中,实例化对象(new)之前的代码。
  3. 构造代码块和普通成员变量并列优先级,按代码中出现的先后顺序执行。
  4. 构造方法。
  5. 最后就是实例化对象(new)之后的代码。

注意:第1步只有在类第一次被加载的时候才运行。如果创建两个对象

new Base();
new Base();

第二次创建对象,就只执行第3步。

有继承的情况

这里创建一个子类Subclass继承上述中的父类Base,同时也使用了工具类Log代码如下:

/**
 * 子类/派生类
 */
public class SubClass extends Base {

    static {
        System.out.println("子类静态代码块 1");
    }

    private static String staticValue = Log.staticFieldInit();

    static {
        System.out.println("子类静态代码块 2");
    }

    {
        System.out.println("子类普通代码块 1");
    }

    private String value = Log.fieldInit();

    {
        System.out.println("子类普通代码块 2");
    }

    SubClass() {
        System.out.println("子类构造方法");
    }

    public static void main(String[] args) {
        System.out.println("new 之前");

        SubClass sub = new SubClass();
        System.out.println("new 之后");
    }
}

输出:

父类静态代码块 1
父类静态成员变量
父类静态代码块 2
子类静态代码块 1
子类静态成员变量
子类静态代码块 2
new 之前
父类构造代码块 1
父类普通成员变量
父类构造代码块 2
父类构造方法
子类普通代码块 1
子类普通成员变量
子类普通代码块 2
子类构造方法
new 之后

结论:

  1. 父类静态代码块和静态成员变量并列优先级,按代码出现先后顺序执行。
  2. 子类静态代码块和静态成员变量并列优先级,按代码出现先后顺序执行。
  3. main方法中实例化对象(new)之前的代码。
  4. 父类构造代码块和普通成员变量并列优先级,按代码出现先后顺序执行。
  5. 父类构造方法。
  6. 子类构造代码块和普通成员变量并列优先级,按代码出现先后顺序执行。
  7. 子类构造方法。
  8. main方法中实例化对象(new)之前的代码。

注意,第1,2步只有在子类第一次被加载时才运行,如果创建两个对象,则第二次创建对象只执行第4,5,6,7步。

总结

在没有继承的情况下,优先级:静态代码块和静态成员变量 > 构造代码块和普通成员变量 > 构造方法。

有继承的情况下,优先级:父类静态代码块和静态成员变量 > 子类静态代码块和静态成员变量 > 父类构造代码块和普通成员变量 > 父类构造方法 > 子类构造代码块和普通成员变量 > 子类构造方法。

main方法是一个静态方法,在通过java命令运行SubClass时,产生的第一个事件就是试图访问SubClass.main(),于是类加载器开始启动并找到SubClass.class文件,对它进行加载时,发现这是一个子类(有extends关键字),于是继续加载它的父类Base,这个过程,不管是否创建了父类对象都会进行。如果父类还有父类,那么还会继续加载,依次类推。在静态代码块和静态成员变量都加载完成后,就会执行main方法中的其他代码,如果遇到了实例化对象的代码,就会按照上述所说的优先级执行代码。

如果对你有帮助就请点个赞吧。

相关文章

  • 类初始化和加载过程

    一、对象的初始化顺序: java类加载器加载类的顺序:http://blog.csdn.net/crazycode...

  • 构造器内部的多态方法的行为

    上一篇 :Java类初始化顺序 上一节我们简单总结了类的初始化顺序。父类(静态变量、静态初始化块)>子类(静态变量...

  • JAVA的类加载顺序

    理解关于java类的加载顺序 首先来捋一捋java类的加载顺序吧 父类静态代码块 》》静态代码初始化,静态属性(带...

  • Java类的初始化顺序

    Java类的初始化顺序 (静态变量、静态代码块)> 类里的 main()(如果有的话) > (变量、初始化块) >...

  • Java类加载与初始化

    今天复习了一下java类加载时的初始化顺序,先记录一下心得,代码后续补上。 类加载时的初始化顺序 1、一般来说,类...

  • Java和Kotlin类的初始化顺序

    Java Java程序初始化的顺序:父类静态变量 -> 父类静态代码块 -> 子类静态变量 -> 子类静态代码块 ...

  • java构造器初始化与清理

    java构造器初始化先后顺序: 若此类继承于某基类,则先初始化基类,以此类推,找到最基本的父类,先对基类进行初始化...

  • 设计模式——工厂,策略,建造者

    Java 类初始化顺序基本分为以下几种:静态块,初始化块,静态方法,构造函数块,静态变量,成员变量对于块顺序,静态...

  • java 类初始化 顺序

    Java 类初始化介绍 java语言在使用过程中最先开始就是初始化,在工作中如果遇到什么问题需 要定位往往到最后也...

  • java类初始化顺序

    1.静态代码块,静态变量,按代码顺序先后执行.2.构造代码块,成员变量,按代码顺序先后执行.3.先执行构造块或成员...

网友评论

      本文标题:Java类的初始化顺序

      本文链接:https://www.haomeiwen.com/subject/jmbuxltx.html