美文网首页
静态代码块、静态变量、成员变量等加载顺序详解

静态代码块、静态变量、成员变量等加载顺序详解

作者: 实力战五渣 | 来源:发表于2019-03-23 17:43 被阅读0次

    静态代码块、静态变量、成员变量等加载顺序详解

    1 单个类的初始化顺序

    一个类 无论创建多少对象,静态数据只占用一份存储区域,且只在类第一次初始化的时候进行静态数据初始化

    顺序如下:

    单个类而言: 静态变量/静态代码块 --> 成员变量(普通代码块) --> 构造方法 --> 静态方法

    构造方法本身也是静态方法

    栗子

    public class TestStatic {
        {
            System.out.println("代码块1");
        }
        /*静态代码块*/
        static {
            System.out.println("静态代码块");
        }
        static Test test = new Test();
    
        String s = "成员变量";
    
        TestStatic (){
            System.out.println(s + "TestStatic 构造方法");
        }
        {
            System.out.println("代码块2");
        }
    
        public static void main(String[] args) {
            new TestStatic();
        }
    }
    
    class Test {
        Test(){
            System.out.println("test构造方法");
        }
    }
    /*结果如下
    静态代码块
    test构造方法
    代码块1
    代码块2
    成员变量TestStatic 构造方法
    
    Process finished with exit code 0
    说明 在加载main 方法之前 需要先加载这个类 
    所以在不实例化这个对象之前的结果是
    静态代码块
    test构造方法
    
    Process finished with exit code 0
    加载顺序: 加载类 --> 静态变量、静态代码块(先后顺序加载) --> 成员变量、一般代码块 --> 构造方法
    

    加载顺序: 加载类 --> 静态变量、静态代码块(先后顺序加载) --> 成员变量、普通代码块 --> 构造方法

    再来个栗子

    class Bowl {
        Bowl(int marker) {
            System.out.println("Bowl(" + marker + ")");
        }
    
        void f1(int marker) {
            System.out.println("f1(" + marker + ")");
        }
    }
    
    class Table {
        static Bowl bowl1 = new Bowl(1);
        Table() {
            System.out.println("Table()");
            bowl2.f1(1);
        }
        void f2(int marker){
            System.out.println("f2(" + marker + ")");
        }
        static Bowl bowl2 = new Bowl(2);
    }
    
    class Cupboard {
        Bowl bowl3 = new Bowl(3);
        static Bowl bowl4 = new Bowl(4);
        Cupboard (){
            System.out.println("Cupboard()");
            bowl4.f1(2);
        }
        void f3(int marker){
            System.out.println("f3(" + marker +  ")");
        }
        static Bowl bowl5 = new Bowl(5);
    }
    
    public class StaticInitialization {
    
        public static void main(String[] args) {
            System.out.println("Creating new Cupboard() in main");
            new Cupboard();
            System.out.println("Creating new Cupboard() in main");
            new Cupboard();
            table.f2(1);
            cupboard.f3(2);
        }
        static Table table = new Table();
        static Cupboard cupboard = new Cupboard();
    }
    
    /**
    结果如下: 
    Bowl(1)
    Bowl(2)
    Table()
    f1(1)
    Bowl(4)
    Bowl(5)
    Bowl(3)
    Cupboard()
    f1(2)
    Creating new Cupboard() in main
    Bowl(3)
    Cupboard()
    f1(2)
    Creating new Cupboard() in main
    Bowl(3)
    Cupboard()
    f1(2)
    f2(1)
    f3(2)
    
    Process finished with exit code 0
    **/
    
    

    父子类初始化顺序

    多个类 其实也差不多,顺序如下:

    父类静态变量、静态代码块 --> 子类静态变量、静态代码块 --> 父类成员变量、普通代码块--> 父类构造方法 --> 子类成员变量、普通代码块--> 子类构造方法

    栗子来了

    /*子类*/
    public class Child extends Parent {
    
        static {
            System.out.println("子类静态代码块");
        }
        static TestChild test = new TestChild();
    
        {
            System.out.println("子类代码块1");
        }
    
        String s = "子类成员变量";
    
        {
            System.out.println("子类代码块2");
        }
    
        Child() {
            System.out.println("子类构造器" + s);
        }
    
        public static void main(String[] args) {
            Parent c = new Child();
        }
    
    }
        class TestChild {
            TestChild (){
            System.out.println("用于测试子类静态变量顺序");
        }
    }
    
    
    /*父类*/
    package com.windy.testBook.five;
    
    /**
     * @Author windy
     * @Desp
     * @Date 2019-03-23 17:13
     */
    public class Parent {
    
        static TestParent test = new TestParent();
    
        static {
            System.out.println("父类静态代码块");
        }
        Parent () {
            System.out.println("父类构造器" + s);
        }
    
        {
            System.out.println("父类代码块1");
        }
    
        String s = "父类成员变量";
    
        {
            System.out.println("父类代码块2");
        }
    }
        class TestParent {
        TestParent (){
            System.out.println("用于测试父类静态变量顺序");
        }
    }
    
    /*结果
    用于测试父类静态变量顺序
    父类静态代码块
    子类静态代码块
    用于测试子类静态变量顺序
    父类代码块1
    父类代码块2
    父类构造器父类成员变量
    子类代码块1
    子类代码块2
    子类构造器子类成员变量
    
    Process finished with exit code 0
    */
    

    静态代码块或者静态变量是对象加载的时候进行的 只加载一次。如上面所有 只有一个存储区域。而成员变量或者普通代码块 每次实例的时候 都会执行一次 而且都优先于构造方法

    相关文章

      网友评论

          本文标题:静态代码块、静态变量、成员变量等加载顺序详解

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