Java初始化块(静态代码块和非静态代码块)

       Java使用构造器来对单个对象进行初始化操作,使用构造器先完成整个Java对象的状态初始化,然后将Java对象返回给程序,从而让该Java对象的信息更加完整。与构造器作用非常类似的是初始化块,它也可以对Java对象进行初始化操作。

初始化块

       初始化块是Java里出现的第四种成员(成员变量、方法和构造器),一个类里可以有多个初始化块,相同类型的初始化块之间有顺序:前面定义的初始化块先执行,后面定义的初始化块后执行。

       初始化块的修饰符只能是static,使用static修饰的初始化块被称为静态代码块。初始化块里的代码可以包含任何可执行语句,包括定义局部变量、调用其他对象的方法,以及使用分之、循环语句等。

       从运行结果可以看出,当创建Java对象时,系统总是先调用该类里定义的初始化块,如果一个类里定义了2个普通初始化块,则前面定义的初始化块先执行,后面定义的初始化块后执行

       初始化块虽然也是Java类的一种成员,但它没有名字,也就没有标识,因此无法通过类、对象来调用初始化块。初始化块只在创建Java对象时隐式执行,而且在构造器执行执行。

       当Java创建一个对象时,系统先为该对象的所有实例变量分配内存(前提是该类已经被加载过了),接着程序开始对这些实例变量进行初始化,其初始化顺序是:先执行初始化块或声明实例变量时指定的初始值(这两个地方指定初始值的执行允许与他们在源代码中的排列顺序相同),在执行构造器指定的初始值。

初始化块和构造器

       从某种程度上来看,初始化块是构造器的补充,初始化块总是在构造器执行之前执行。系统同样可使用初始化块来进行对象的初始化操作。

       与构造器不同的是,初始化块是一段固定执行的代码,它不能接受任何参数。因此初始化块对同一个累的所有对象多进行的初始化处理不同。基于这个原因,不难发现初始化块的基本用法,如果有一段初始化处理代码对所有对象完全相同,且无需接收任何参数,就可以把这段初始化处理代码提取到初始化块中

       实际上初始化块只是一个假象,使用javac命令编译Java类后,该Java类中的初始化块会消失——初始化块中代码会被“还原”到每个构造器中,且位于构造器所有代码的前面。

静态初始化快

       如果定义初始化块时使用了static修饰符,则这个初始化块就变成了静态初始化块,也被称为类初始化块(普通初始化块负责对对象执行初始化,类初始化块则负责对类进行初始化)。静态初始化块是类相关的,系统将在类初始化阶段执行静态初始化块,而不是在创建对象时才执行。因此静态初始化块总是比普通初始化块先执行。

       静态初始化块是类相关的,用于对整个类进行初始化处理,通常用于对类变量执行初始化处理。静态初始化块不能对实例变量进行初始化处理。

注意:
       静态初始化块也被称为类初始化块,也属于类的静态成员,同样需要遵循静态成员不能访问非静态成员的规则,因此静态初始化块不能访问非静态成员,包括不能访问实例变量和实例方法。

       与普通初始化块类似的是,系统在类初始化阶段执行静态初始化块时,不仅会执行本类的静态初始化块,而且还会一直上溯到java.lang.Object类(如果它包含静态初始化块),先执行java.lang.Object类的静态初始化块(如果有),然后执行其父类的静态初始化块……最后才执行该类的静态初始化块,经过这个过程,才完成对该类的初始化过程。只有当雷初始化完成后,才可以在系统中使用这个类,包括访问这个类的类方法、类变量或者用这个类来创建实例。

代码块执行顺序

       1.主调类的静态代码块
       2.对象父类的静态代码块
       3.对象的静态代码块
       4.对象父类的非静态代码块
       5.对象父类的构造函数
       6.对象的非静态代码块
       7.对象的构造函数

区别

静态代码块,在虚拟机加载类的时候就会加载执行,而且只执行一次;

非静态代码块,在创建对象的时候(即new一个对象的时候)执行,每次创建对象都会执行一次。

相同点:都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,
    一般在代码块中对一些static变量进行赋值。
不同点:静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。
    静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new
    一次就执行一次。非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。

代码示例

package codes;

class Root {

    static{
        System.out.println("Root的静态初始化块");
    }

    {
        System.out.println("Root的普通初始化块");
    }

    public Root(){
        System.out.println("Root的五参数构造器");
    }
}

class Mid extends Root{

    static{
        System.out.println("Mid的静态初始化块");
    }

    {
        System.out.println("Mid的普通初始化块");
    }

    public Mid(){
        System.out.println("Mid的五参数构造器");
    }

    public Mid (String msg){
        //通过this来调用同一类中重载的构造器
        this();
        System.out.println("Mid的带参数构造器,其参数值:"+msg);
    }
}

class Leaf extends Mid{

    static{
        System.out.println("Leaf的静态初始化块");
    }

    {
        System.out.println("Leaf的普通初始化块");
    }

    public Leaf(){
        //通过super调用父类中有一个字符串参数的构造器
        super("Java程序设计");
        System.out.println("执行Leaf的构造器");
    }
}
public class Test {

    public static void main(String[] args) {

        new Leaf();
        System.out.println("---------------");
        new Leaf();

    }

}

代码示例结果如下:

Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的五参数构造器
Mid的普通初始化块
Mid的五参数构造器
Mid的带参数构造器,其参数值:Java程序设计
Leaf的普通初始化块
执行Leaf的构造器
---------------
Root的普通初始化块
Root的五参数构造器
Mid的普通初始化块
Mid的五参数构造器
Mid的带参数构造器,其参数值:Java程序设计
Leaf的普通初始化块
执行Leaf的构造器
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值