java初始化

系列文章目录

第一章 万事万物皆对象
第二章 java构造器
第三章 java访问权限
第四章 java初始化
第五章 java继承
第六章 java重载与重写
第七章 java接口和抽象类
第八章 java数组
第九章 java内部类
第十章 java时间操作
第十一章 final关键字
第十二章 java字符串
第十三章 java异常
第十四章 java泛型
第十五章 java IO操作
第十六章 java NIO操作
第十七章 java zip压缩
第十八章 java反射
第十九章 java反射之Type接口
第二十章 java8流式操作
第二十一章 java8函数式编程


文章目录

    • 初始化顺序
      • 验证类加载
        • Initable和Initable1结果分析
        • Initable2结果分析
        • Initable3和Initable4结果分析


原文链接 https://zhhll.icu/2020/java基础/面向对象/4.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编译器会默认提供一个无参构造器,但是如果提供了自己的构造器,编译器将不会再生成默认构造器。

你可能感兴趣的:(java基础,java)