Java 之 类初始化

摘要:
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)是按照顺序执行的。

    Java 之 类初始化第1张

  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>() 方法只执行一次;

免责声明:文章转载自《Java 之 类初始化》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇汇编指令分布式算法(一致性Hash算法)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

开源项目 log4android 使用方式详解

      话不多说, 直接上主题。       log4android 是一个类似于log4j的开源android 日志记录项目。 项目基于 microlog 改编而来, 新加入了对文件输出的各种定义方式。 项目地址: 点击这里  (https://github.com/lisicnu/Log4Android) 使用方式:  0. 导入包.     项目...

C99规范

1. 增加restrict指针    C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。restrict数据类型不改变程序的语义。    如果某个函数定义了两个restr...

K8S从入门到放弃系列-(1)环境初始化

一、系统规划  主机名 IP   组件  k8s-master01 10.10.0.18 etcd、kube-apiserver、kube-controller-manager、kube-scheduler  k8s-master02 10.10.0.19 etcd、kube-apiserver、kube-controller-manager、...

C++中的动态绑定

C++中基类和派生类遵循类型兼容原则:即可用派生类的对象去初始化基类的对象,可用派生类的对象去初始化基类的引用,可用派生类对象的地址去初始化基类对象指针。 C++中动态绑定条件发生需要满足2个条件: 1:只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不能进行动态绑定 2:必须通过基类类型的引用或指针进行函数调用 基类类型引用和...

Socket编程 (一)

<<Linux 网络编程>>摘要           注意: 其中的大部分成员是网络字节序(大端字节序); 编程: 服务器先要做的事情: socket() 初始化Socket bind() 绑定本地端口 listen() 监听端口 accept() 响应客户端请求 一个例子   客户端(Windows 系统, Java...

openlayers3入门教程

                                                                                                           openlayers3入门教程 摘要        OpenLayers 3对OpenLayers网络地图库进行了根本的重新设计。版本2虽然被...