• 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>() 方法只执行一次;
  • 相关阅读:
    链接
    列表
    Android Studio AVD 虚拟机 联网 失败
    docker error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.29/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuratio
    JSP Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING
    js jsp form
    intellij jsp 中文乱码
    [转载]在Intellij Idea中使用JSTL标签库
    windows pybloomfilter
    docker mysql
  • 原文地址:https://www.cnblogs.com/niujifei/p/13982895.html
Copyright © 2020-2023  润新知