美文网首页
静态代码块和非静态代码块

静态代码块和非静态代码块

作者: 明丶夷 | 来源:发表于2019-03-18 16:45 被阅读0次

    之前一直只知道有静态代码块。后来才知道还有一个非静态代码块。


    静态代码块是指由 static 修饰的大括号里的一段代码,那么非静态代码块就是没有修饰的大括号里的一段代码。就像下面:

    # 静态代码块
    static {
      若干代码,随便写点啥吧。。。。
    }
    
    # 非静态代码块
    {
      若干代码,随便写点啥吧。。。。
    }
    

    他们的共同特点是:方法名、作用域、返回值、参数一概没有。

    详情解析

    我们先提出几个问题:

    1. 静态和非静态这两种代码块的区别是什么?
    2. 它们之间的执行顺序是怎么样?和构造函数间的执行顺序又是怎么样的?
    3. 当有继承情况存在的时候,它们的执行顺序又是怎么样?

    带着问题,进行接下来的代码分析:

    package com.sunyu.javaBase.aboutClass;
    
    public class LoadOrder {
        public static void main(String[] args) {
            /**
            一般情况下的代码测试
             */
            parentTest();
    
            /**
             * 有继承情况存在下的代码测试
             */
            childrenTest();
        }
    
        /**
         * 父类测试
         */
        public static void parentTest() {
            Parent parent = new Parent();
            System.out.println();
            System.out.println("-------- 这是两次实例化的分割线 ---------");
            System.out.println();
            parent = new Parent("父类测试");
        }
    
        /**
         * 子类测试
         */
        public static void childrenTest() {
            Children children = new Children();
            System.out.println();
            System.out.println("-------- 这是两次实例化的分割线 ---------");
            System.out.println();
            children = new Children("子类测试");
    
        }
    
    }
    
    class Parent {
        {
            System.out.println("父类:执行非静态代码块");
        }
    
        static {
            System.out.println("父类:执行静态代码块");
        }
    
        static String name;
    
        Parent() {
            System.out.println("父类:执行无参构造函数");
        }
    
        Parent(String name) {
            System.out.println("父类:执行有参构造函数 --->" + name);
        }
    }
    
    class Children extends Parent {
        {
            System.out.println("子类:执行非静态代码块");
        }
    
        static {
            System.out.println("子类:执行静态代码块");
        }
    
        static String name;
    
        Children() {
            System.out.println("子类:执行无参构造函数");
        }
    
        Children(String name) {
            System.out.println("子类:执行有参构造函数 --->" + name);
        }
    }
    

    在上面的代码中定义了:主类 LoadOrder父类 Parent子类 Children

    执行 parentTest(),测试代码块之间,以及代码块与构造函数之间的执行顺序。执行结果如下:

    image.png
    parentTest() 中 Parent 实例化了两次。从上面的执行结果来看:
    • 静态代码块执行了一次。众所周知,是类在初始化的时候执行的,也只执行这一次。
    • 非静态代码块执行了两次,而 Parent 实例化了两次。则非静态代码块是在类被实例化的时候执行的,类每实例化一次,则非静态代码块执行一次
    • 两种代码块的执行顺序都在构造函数之前。但是静态代码块在非静态之前。

    执行 childrenTest(),测试在继承情况下,代码块,构造函数间的执行顺序。执行结果如下:

    image.png
    childrenTest()中,Children 实例化了两次。从上面的执行结果看:
    • 不管是父类还是子类,静态代码块优先执行。
    • 在所有的静态代码块执行完后,执行父类相关的代码。先执行父类非静态代码块,再执行父类构造方法;之后执行子类非静态代码块,再执行子类构造方法

    结论
    • 静态代码块是在类被加载的时候(即初始化)去执行,且只执行一次
    • 非静态代码块是在类被实例化的时候执行。每被实例化一次,就会被执行一次。
    • 无继承的情况下:执行顺序为:静态代码块 ——> 非静态代码块 ——> 构造函数
    • 有继承的情况下:执行顺序为:父类,子类静态方法 ——> 父类非静态代码块、构造函数 ——> 子类非静态代码块、构造函数

    相关文章

      网友评论

          本文标题:静态代码块和非静态代码块

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