Java类初始化执行流程解析

 更新时间:2021年05月02日 07:31:18   作者:飘渺红尘✨  
这篇文章主要介绍了Java类初始化执行流程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

 测试代码:  

package com.test.ClassLaoderTest;

public  class test1 {
    public static String s_variable = "静态变量";
    public String init_variable = "公开的变量";
    private String p_variable = "私有的变量";
    //静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("静态代码块初始化执行了");
    }

    //初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("初始化代码块执行沦");
    }

    //构造方法
    public test1(){
        System.out.println("我是构造方法");
    }

    public static void main(String[] args) {

    }

}

  直接运行:

    

  main方法里面不做任何调用的情况下,自动调用的是静态代码块和静态变量

  (2)调用静态变量和静态方法:

    测试代码:    

package com.test.ClassLaoderTest;


public class test1 {
    public static String s_variable = "静态变量";
    public String init_variable = "公开的变量";
    private String p_variable = "私有的变量";
    //静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("静态代码块初始化执行了");
    }

    //初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("初始化代码块执行沦");
    }

    //构造方法
    public test1(){
        System.out.println("我是构造方法");
    }

    //静态方法
    public static void test1(){
        System.out.println("这是静态方法");
    }
    public static void main(String[] args) {
        System.out.println(test1.s_variable);
        test1.test1();
    }

}

  运行:

  

  结论:当我调用静态方法/静态变量时,只会家在静态代码块,其余的代码块/构造方法不会被加载

  (3)创建对象:

package com.test.ClassLaoderTest;


public class test1 {
    public static String s_variable = "静态变量";
    public String init_variable = "公开的变量";
    private String p_variable = "私有的变量";
    //静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("静态代码块初始化执行了");
    }

    //初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("初始化代码块执行了");
    }

    //构造方法
    public test1(){
        System.out.println("我是构造方法");
    }

    //静态方法
    public static void test1(){
        System.out.println("这是静态方法");
    }
    public static void main(String[] args) {
        test1 t1 = new test1();
    }

}

  运行结果:

    

  输出内容: 

静态变量
静态代码块初始化执行了
公开的变量
私有的变量
初始化代码块执行了
我是构造方法

  结论:当创建对象/实例化的时候,调用顺序:静态代码块->初始化代码->构造方法,最后执行的才是构造方法

  (4)有继承关系下的类初始化执行流程:

   环境:

    父类:

package com.test.ClassLaoderTest;

public class father {
    public static String s_variable = "父类静态变量";
    public String init_variable = "父类公开的变量";
    private String p_variable = "父类私有的变量";
    //父类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("父类静态代码块初始化执行了");
    }

    //父类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("父类初始化代码块执行了");
    }

    //构造方法
    public father(){
        System.out.println("我是父类构造方法");
    }

    //父类静态方法
    public static void test1(){
        System.out.println("这是父类静态方法");
    }
}

    test1.java:

    继承其父类father:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {
        
    }
}

  main方法不做任何操作,运行:

    

 只要extends继承了,优先调用父类静态代码块

(5)有继承关系下的调用静态方法:

    修改子类即可:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {
        test1.test1();
        father.test1();
    }
}

  运行:

      

  结果:

父类静态变量
父类静态代码块初始化执行了
子类静态变量
子类静态代码块初始化执行了
这是子类静态方法
这是父类静态方法

  main方法中,谁优先调用静态方法,就优先加载谁

 (6)有继承关系下的创建对象:

    代码:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {
        test1 t1 =new test1();
    }
}

  运行:

   

  结果:

父类静态变量
父类静态代码块初始化执行了
子类静态变量
子类静态代码块初始化执行了
父类公开的变量
父类私有的变量
父类初始化代码块执行了
我是父类构造方法
子类公开的变量
子类私有的变量
子类初始化代码块执行了
我是子类构造方法

  结论:通过结果会发现,不管是子类还是父类静态代码块,静态代码块在哪里都是爸爸级别,最先加载的,当创建test1对象的时候,优先加载的是父类代码块,那么他的初始化执行流程如下:父类静态代码块>子类静态代码块>父类初始化代码块>父类构造方法>子类代码块>子类构造方法

(7) 有继承关系下的创建父类对象:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {
        father father = new father();
    }
}

 运行:

  

  结果:

父类静态变量
父类静态代码块初始化执行了
子类静态变量
子类静态代码块初始化执行了
父类公开的变量
父类私有的变量
父类初始化代码块执行了
我是父类构造方法

  结论:优先执行的是两个类的静态代码块,然后是父类型的代码块和构造方法,而子类的代码块和构造方法没有被执行是因为没有实例化子类,所以肯定是没有他的,那么只有在创建对象的时候,才会调用代码块和构造方法

到此这篇关于Java类初始化执行流程的文章就介绍到这了,更多相关Java类初始化执行流程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java发送短信系列之限制发送频率

    java发送短信系列之限制发送频率

    这篇文章主要为大家详细介绍了java发送短信系列之限制发送频率,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • java虚拟机原理:类加载过程详解

    java虚拟机原理:类加载过程详解

    这篇文章主要介绍了Java中类加载过程全面解析,具有一定参考价值,需要的朋友可以了解下,希望能够给你带来帮助
    2021-09-09
  • Java RateLimiter的限流详解

    Java RateLimiter的限流详解

    这篇文章主要为大家详细介绍了Java RateLimiter的限流,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • java获取包下被指定注解的类过程解析

    java获取包下被指定注解的类过程解析

    这篇文章主要介绍了java获取包下被指定注解的类过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • 最新log4j2远程代码执行漏洞(附解决方法)

    最新log4j2远程代码执行漏洞(附解决方法)

    Apache Log4j2 远程代码执行漏洞攻击代码,该漏洞利用无需特殊配置,经多方验证,Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响,本文就介绍一下解决方法
    2021-12-12
  • Spring依赖注入(DI)两种方式的示例详解

    Spring依赖注入(DI)两种方式的示例详解

    这篇文章主要介绍了Spring依赖注入(DI)的两种方式:setter注入和构造器注入。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-06-06
  • SpringBoot项目启动时提示程序包不存在和找不到符号的处理方法

    SpringBoot项目启动时提示程序包不存在和找不到符号的处理方法

    最近接手同事开发的一个Springboot工作项目,从svn上整体拉取下来后,构建完成后,启动的时候遇到了程序包找不到的情况,所以本文记录了SpringBoot项目启动时提示程序包不存在和找不到符号的处理方法,需要的朋友可以参考下
    2024-05-05
  • Java中如何调用cmd压缩文件

    Java中如何调用cmd压缩文件

    以下是对Java调用cmd压缩文件的实现方法进行了分析介绍,需要的朋友可以参考下
    2013-07-07
  • java代码之谜运算符篇

    java代码之谜运算符篇

    从最简单的运算符加号(+)说起,加号(+)是个二元运算符——也就是说,加号只把两个数联接起来,从来不把第三个或者更多的联接起来
    2012-11-11
  • Java注解详解之@Override注解

    Java注解详解之@Override注解

    这篇文章主要给大家介绍了关于Java注解之@Override注解的相关资料,@Override是Java中的一个注解,表示一个方法是重写(Override)了父类中的方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11

最新评论