美文网首页
java基础之初始化顺序

java基础之初始化顺序

作者: 墨线宝 | 来源:发表于2023-10-05 14:09 被阅读0次

    初始化顺序

    在类中变量定义的顺序决定了它们初始化的顺序。在创建任何java对象时,都是依次调用父类非静态初始化块、父类构造器执行初始化、本类的非静态初始化块、本类构造器执行初始化

    public class House {
        // 构造器之前
        Window w1 = new Window(1);
    
        House(){
            System.out.println("House()");
            Window window = new Window(11);
        }
    
        // 构造器之后
        Window w2 = new Window(2);
    
        void f(){
            System.out.println("f()");
        }
    
        Window w3 = new Window(3);
    
        public static void main(String[] args) {
            House house = new House();
            house.f();
        }
    }
    
    public class Window {
        public Window(int mark){
            System.out.println("Window("+mark+")");
        }
    }
    

    执行结果

    Window(1)
    Window(2)
    Window(3)
    House()
    Window(11)
    f()
    

    由执行结果可知,在进行对象实例化时先执行初始化块,再执行构造器主体部分

    验证类加载

    public class Initable {
        // 非编译期常量
        public static final int COUNT =new Random().nextInt(1000);
        static {
            System.out.println("Initable初始化");
        }
    }
    
    
    public class Initable1 {
        // 编译期常量
        public static final int COUNT = 47;
    
        static {
            System.out.println("Initable1初始化");
        }
    }
    
    public class Initable2 {
        public static int COUNT = 56;
    
        static {
            System.out.println("Initable2初始化");
        }
    }
    
    public class Initable3 {
        public static int COUNT = 33;
    
        static {
            System.out.println("Initable3初始化");
        }
    }
    
    public class Initable4 {
        public static int COUNT = 44;
    
        static {
            System.out.println("Initable4初始化");
        }
    }
    
    public class Test {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            System.out.println("Initable---------------");
            System.out.println(Initable.COUNT);
            System.out.println("Initable1---------------");
            System.out.println(Initable1.COUNT);
            System.out.println("Initable2---------------");
            System.out.println(Initable2.COUNT);
            System.out.println("Initable3---------------");
            Class<Initable3> clazz = Initable3.class;
            System.out.println("Initable4---------------");
            Class.forName("com.zhanghe.study.init.Initable4");
        }
    }
    
    
    
    结果:
    Initable---------------
    Initable初始化
    457
    Initable1---------------
    47
    Initable2---------------
    Initable2初始化
    56
    Initable3---------------
    Initable4---------------
    Initable4初始化
    

    Initable和Initable1结果分析

    对于static final的值是一个编译期常量的话(如Initable1.COUNT),获取这个值时不需要对Initable1进行初始化就可以读取,如果用static final的值不是一个编译期常量(如Initable.COUNT),访问这个变量会强制对该类进行初始化

    Initable2结果分析

    对于一个仅仅是static修饰的字段而不是final的,在读取这个字段之前,需要为该字段分配存储空间以及初始化该存储空间

    Initable3和Initable4结果分析

    使用.class语法不会对类进行初始化,而使用Class.forName()来产生Class引用会直接引发类的初始化

    注意:如果没有显式的编写构造器的话,java编译器会默认提供一个无参构造器,但是如果提供了自己的构造器,编译器将不会再生成默认构造器。

    https://zhhll.icu/2020/java基础/面向对象/4.java基础之初始化/

    本文由mdnice多平台发布

    相关文章

      网友评论

          本文标题:java基础之初始化顺序

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