一、类初始化过程
1、
2、
二、静态代码块
1、作用
Java静态代码块的作用:Java静态代码块中的代码会在类加载JVM时运行,且只被执行一次,也就是说这些代码不需要实例化类就能够被调用。一般情况下,如果有些代码必须在项目启动的时候就执行的时候,就需要使用静态代码块。
Java静态代码块的用法:一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只被执行一次,静态块常用来执行类属性的初始化。
2、执行时机
(1)在虚拟机加载类的时候就会加载执行,而且只执行一次;
(2)静态代码块会在第一次使用这个类之前执行,即在类初始化时执行;
3、总结
(1)它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的。
(2)静态代码块其实就是给类初始化的,而非静态代码块是给对象初始化的;
(3)静态代码块中的变量是局部变量,与普通函数中的局部变量性质没有区别;
(4)一个类中可以有多个静态代码块;
4、静态代码块与非静态代码块对比
一般情况下,如果有些代码必须在项目启动的时候就执行,需要使用静态代码块。这种代码是主动执行的,需要在项目启动的时候就初始化。
有些代码是在不创建对象的情况下,由其他程序来调用,需要使用静态方法。这种代码是被动执行的,静态方法在类加载的时候就已经加载,可以用类名直接调用
比如main方法就必须是静态的 这是程序入口
两者的区别就是:静态代码块是自动执行的,而静态方法是被调用的时候才执行的。
静态代码块与非静态代码块区别:
静态代码块,在虚拟机加载类的时候就会加载执行,而且只执行一次;
非静态代码块,在创建对象的时候(即new一个对象的时候)执行,每次创建对象都会执行一次
相同点:都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,
一般在代码块中对一些static变量进行赋值。
不同点:静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。
静态代码块只在第一次类加载时执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。
非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。
三、类初始化方法
1、类初始化方法:<clinit>()
类初始化方法,一个类只有一个。它是由编译器编译生成的,由两部分组成:
(1)静态变量的显式赋值代码;
(2)静态代码块的代码;
其中(1)和(2)是按照顺序执行的。
2、父子类的类初始化
一个类初始化时会先检查它的父类是否初始化,如果父类没有初始化,那么先初始化父类,因为一个类只要初始化一次。
父类的初始化<clinit>():
① 父类的静态变量的显示赋值;
② 父类的静态代码块;
子类的初始化<clinit>():
① 子类的静态变量的显示赋值;
② 子类的静态代码块;
Tips:静态方法是不能被重写的,静态方法在编译时就确定了,不需要再运行时动态绑定。
Demo:
1 public class TestClassInit {
2 public static void main(String[] args) {
3 /*Father f = new Father();
4 System.out.println("-------------------");
5 Son s = new Son();*/
6
7 Son s = new Son();
8
9 /*Father f = new Son();//多态引用
10 System.out.println("----------------");
11 f.assign();//静态方法在编译期间就确定了,不需要在运行时动态绑定
12 */ }
13 }
14 class Father{
15 private static String info = assign();
16 static{
17 System.out.println("(1)父类的静态代码块");
18 }
19 public static String assign(){
20 System.out.println("(3)assign()方法");
21 return "Father";
22 }
23 }
24 class Son extends Father{
25 private static String info = assign();
26 static{
27 System.out.println("(2)子类的静态代码块");
28 }
29 public static String assign(){
30 System.out.println("(4)assign()方法");
31 return "Son";
32 }
33 }
3、
4、
四、总结
类初始化过程:
1、一个类要创建实例需要先加载并初始化该类,main 方法所在的类需要先加载和初始化;2、一个子类要初始化需要先初始化父类;3、一个类初始化就是执行 <clinit> 方法,<clinit>() 方法由静态类变量显示赋值代码和静态代码块组成;类变量显示赋值代码和静态代码块代码从上到下顺序执行,<clinit>() 方法只执行一次;