Java 之 类初始化

一、类初始化过程

  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、

  2、

 

五、

六、总结

  类初始化过程:
1、一个类要创建实例需要先加载并初始化该类,main 方法所在的类需要先加载和初始化;
2、一个子类要初始化需要先初始化父类;
3、一个类初始化就是执行 <clinit> 方法,<clinit>() 方法由静态类变量显示赋值代码和静态代码块组成;
类变量显示赋值代码和静态代码块代码从上到下顺序执行,<clinit>() 方法只执行一次;
原文地址:https://www.cnblogs.com/niujifei/p/13982895.html