ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 程序初始化顺序

2022-05-15 16:01:11  阅读:99  来源: 互联网

标签:初始化 顺序 Java System static println public out


前置知识

  • 初始化块:类中直接用 {} 定义,每一次创建对象时执行
  • 静态代码块:用 staitc 声明,JVM加载类时执行,仅执行一次

Java 程序初始化顺序

对于静态变量、静态初始化块、变量、初始化块、构造器,它们初始化顺序流程如下文字描述,示意图如下

静态变量、静态代码块 > 变量、初始化块 > 构造器

静态变量和静态代码块两个的初始化顺序是靠它们俩的位置决定的

单个类的初始化

单个类的初始化
public class Example {

    public static String STR = "静态成员变量";

    public String variable = "普通成员变量";

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

    {
        System.out.println(variable);
        System.out.println("初始化块");
    }

    public Example(){
        System.out.println("构造器");
    }

    public static void main(String[] args) {
        System.out.println("Java 程序初始化顺序");
        Example a = new Example();
    }
}
结果
静态成员变量
静态代码块
Java 程序初始化顺序
普通成员变量
初始化块
构造器

调换静态成员变量和静态代码块顺序

静态成员变量在先,并做初始化动作
public class Example {

    public static Example example1 = new Example();
    public static Example example2 = new Example();

    {
        System.out.println("构造块");
    }

    static {
        System.out.println("静态块");
    }

    public Example(){
        System.out.println("构造器");
    }

    public static void main(String[] args) {
        System.out.println("Java初始化顺序");
        Example example = new Example();
    }
}
结果
构造块  ---->(example1实例)
构造器  ---->(example1实例)
构造块  ---->(example2实例)
构造器  ---->(example2实例)
静态块
Java初始化顺序
构造块  ---->(example实例)
构造器  ---->(example实例)
静态成员变量在后,并做初始化动作
public class Example {

    public Example(){
        System.out.println("构造器");
    }

    {
        System.out.println("构造块");
    }

    static {
        System.out.println("静态块");
    }

    public static Example example1 = new Example();
    public static Example example2 = new Example();

    public static void main(String[] args) {
        System.out.println("Java初始化顺序");
        Example example = new Example();
    }
}
结果
静态块
构造块  ---->(example1实例)
构造器  ---->(example1实例)
构造块  ---->(example2实例)
构造器  ---->(example2实例)
Java初始化顺序
构造块  ---->(example实例)
构造器  ---->(example实例)
静态变量在前,并不做初始化
public class Example {

    public static Example example1;
    public static Example example2;

    {
        System.out.println("构造块");
    }

    static {
        System.out.println("静态块");
    }

    public Example(){
        System.out.println("构造器");
    }

    public static void main(String[] args) {
        System.out.println("Java初始化顺序");
        Example example = new Example();
    }
}
结果
静态块
Java初始化顺序
构造块  ---->(example实例)
构造器  ---->(example实例)

具有继承关系的初始化

父类
public class Father {

    public static String F_STR = "父类-静态成员变量";

    public String f_variable = "父类-普通成员变量";

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

    {
        System.out.println(f_variable);
        System.out.println("父类-初始化块");
    }

    public Father(){
        System.out.println("父类-构造器");
    }
}
子类
public class Subclass extends Father{

    public static String S_STR = "子类-静态成员变量";

    public String s_variable = "子类-普通成员变量";

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

    {
        System.out.println(s_variable);
        System.out.println("子类-初始化块");
    }

    public Subclass(){
        System.out.println("子类-构造器");
    }

    public static void main(String[] args) {
        System.out.println("Java 程序初始化顺序");
        Subclass subclass = new Subclass();
    }
}
结果
父类-静态成员变量
父类-静态代码块
子类-静态成员变量
子类-静态代码块
Java 程序初始化顺序
父类-普通成员变量
父类-初始化块
父类-构造器
子类-普通成员变量
子类-初始化块
子类-构造器

初始化说明

  1. 访问子类的main(),于是装载器就会寻找已经编译的子类class文件。在装载的过程中,装载器注意到它有一个基类,于是它再装载基类。不管创不创建基类对象,这个过程总会发生。如果基类还有基类,那么第二个基类也会被装载,依此类推
  2. 执行根基类的static初始化,然后是下一个派生类的static初始化,依此类推。这个顺序非常重要,因为派生类的static初始化有可能要依赖基类成员的正确初始化
  3. 当所有必要的类都已经装载结束,开始执行main()方法体,并用new Subclass()创建对象
  4. 类Subclass存在父类,则调用父类的构造函数,可以使用super来指定调用哪个构造函数
    1. 基类的构造过程以及构造顺序,同派生类的相同。首先基类中各个变量按照字面顺序进行初始化,然后执行基类的构造函数的其余部分
  5. 对子类成员数据按照它们声明的顺序初始化,执行子类构造函数的其余部分

不会初始化子类情况

不会初始化子类的情况

public class Father {
    
    public static int number = 123;

    public static final int number2 = 456;
    
    static{
        System.out.println("父类-静态代码块");
    }

    {
        System.out.println("父类-构造块");
    }

    public Father(){
        System.out.println("父类-构造器");
    }
}

 class Subclass extends Father {
     
    static{
        System.out.println("子类-静态代码块");
    }

     {
         System.out.println("子类-构造块");
     }

     public Subclass(){
         System.out.println("子类-构造器");
     }
}

class Test {
    public static void main(String[] args) {
        System.out.println(Subclass.number);
        System.out.println("-------------------------");
        System.out.println(Subclass.number2);
        System.out.println("-------------------------");
        Subclass[] s = new Subclass[10];
    }
}
结果

父类-静态代码块
123
-------------------------
456
-------------------------

标签:初始化,顺序,Java,System,static,println,public,out
来源: https://www.cnblogs.com/52-IT-y/p/16273422.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有