• 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之hashCode的作用和equals方法的重构规则
    Java-IO流之File操作和Properties操作
    Java-IO流之转换流的使用和编码与解码原理
    Java-IO 字节流的使用和效率比较
    Java-IO流之BufferedReader 和BufferedWriter的使用和原理
    二分查找
    leetcode530 二叉搜索树的最小绝对差
    leetcode94 二叉树的中序遍历
    leetcode17电话号码字母组合
    leetcode26 删除排序数组中的重复项
  • 原文地址:https://www.cnblogs.com/piaomiaohongchen/p/14723021.html
Copyright © 2020-2023  润新知