在Java中除了使用构造器类对单个对象进行初始化操作外,我们还可以通过初始化块来实现。在一个类中可以有多个初始化块,相同类型的初始化块之间有顺序:前面定义的初始化块先执行,后面定义的初始化块后执行。使用static修饰的初始化块,称为静态初始化块,在初始化块中可以定义局部变量、调用其他对象的方法,以及使用分支、循环语句等。
静态初始化块:
执行优先级高于非静态的初始化块,它会在对象装载到系统的时候执行一次,执行完成便销毁,它仅能初始化类变量,即static修饰的数据成员。
非静态初始化块:
执行的时候如果有静态初始化块,先执行静态初始化块再执行非静态初始化块,在每个对象生成时都会被执行一次,它可以初始化类的实例变量。非静态初始化块会在构造函数执行时,在构造函数主体代码执行之前被运行。
下面程序就定义了初始化块:
- class Person{
- {
- int num=25;
- System.out.println("普通初始化块1");
- }
- static{
- int num=45;
- System.out.println("静态初始化块");
- }
- {
- int num=25;
- System.out.println("普通初始化块2");
- }
- public Person(){
- System.out.println("无参构造器");
- }
- }
- public class MainTest {
- public static void main(String[] args) {
- new Person();
- }
- }
输出结果如下:
静态初始化块
普通初始化块1
普通初始化块2
无参构造器
从运行结果可以看出,当创建Java对象时,系统总是先调用静态初始化块,之后按顺序执行普通初始化块,最后才执行构造器。静态初始化块是类相关的,用于对整个类进行初始化处理,静态初始化块也被称为类初始化块,也属于类的静态成员,因此不能访问非静态成员。
最后值得指出的是:当JVM第一次主动使用某个类时,系统会在类准备阶段为该类的所有静态Field分配内存,在初始化阶段负责初始化这些静态Field,初始化静态Field就是执行类初始化代码或者声明类Field时指定的初始值。
首先有三个概念需要了解:
一.静态初始化:是指执行静态初始化块里面的内容。
二.实例初始化:是指执行实例初始化块里面的内容。
三.构造方法:一个名称跟类的名称一样的方法,特殊在于不带返回值。
我们先来看一段程序结果:
- package com;
- class Book{
- public static int booksum=0;//静态变量
- static{//这是静态初始化块
- print();
- System.out.println("this is static block");
- }
- {//实例初始化块
- System.out.println("初始化块:"+booksum);
- }
- public Book(){//构造方法
- System.out.println("this is Book's constructor~");
- booksum+=1;
- }
- public static void print(){//静态方法
- System.out.println("this is static method~");
- }
- public static void main(String []args){
- //Book book=new Book();
- }
- }
执行结果:
this is static method~
this is static block
如果把
- public static void main(String []args){
- //Book book=new Book();
- }
this is static method~
this is static block
初始化块:0
this is Book's constructor~
总结:
仅从代码执行的角度来探讨Java加载类、创建对象的过程,并没有深入到JVM的机制中去。
1.一个对象第一次被创建时,先要加载该对象所属的类,即对应的.class文件,当然如果类已经加载,再次创建该类的对象时,就不再需要重新加载类了。而一个类加载的时候,有三个部分需要加载,一个是静态变量,再然后是静态方法,然后是静态初始化块。 (见到第一次执行结果就知道了,由于没有创建实例所以初始化块不执行)
2.然后开始创建该类的实例了,当然如果静态方法跟静态初始化对象中有对象的创建时,就继续加载该对象的类,当然已经加载了该对象的类的话就不需要再次加 载了。那么对象实例的创建过程是什么呢?首先是成员变量的引入,然后是实例初始化块,之后才是构造方法,构造方法执行完成之后才算把这个对象给创建出来了。
在这个过程中,真正可以编写执行代码的地方有三个,静态初始化、实例初始化以及构造方法。从以上的分析中我们可以看到,这三个代码块的执行顺序是先类的静态初始化,再实例初始化,最后执行构造方法。也就是说,静态初始化是属于类加载的过程,所以它只执行一次,而实例初始化是每个对象创建时都会执行一次,而构造方法跟实例初始化其实也差不多,不过它在实例初始化之后执行,而且构造方法可以重载多个,执行哪个构造方法是根据你的选择来的。
可以把main () 函数加一条语句看看:
- public static void main(String []args){
- Book book=new Book();
- Book book1=new Book();
- }
this is static method~
this is static block
初始化块:0
this is Book's constructor~
初始化块:1
this is Book's constructor~
这说明实例初始化是每个对象创建时都会执行的。