Java 的构造器和初始化块之间的区别

Java构造器与初始化块详解
本文深入探讨Java中构造器和初始化块的作用与区别,解释如何使用初始化块提高代码复用性和可维护性,同时解析静态初始化块的执行时机及其应用场景。

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

1、使用初始化块

一个类里可以有多个初始化块,前面定义的初始化块先执行,后面定义的初始化块后执行。初始化块虽然也是 Java 类的一个成员,但是它没有名字,也就没有标识,因此无法通过类、对象来调用初始化块。初始化块的修饰符只能是 static ,使用 static 修饰的初始化块被称为类初始块(静态初始块)。初始化块里可以包含任意执行语句,包括定义局部变量,调用其他对象的方法,以及使用分支和循环语句。

public class Person
{
    //定义一个初始化块
    {
        int a = 6;
        if( a > 4 )
        {
            System.out.println("Person定义的初始化块:局部定量a的值大于4");
        }
        System.out.println("Person定义的初始化块");
    }
    {
        System.out.println("Person定义的第二个初始化块");
    }
    public Person
    {
        System.out.println("Person类的无参构造函数");
    }
    public static void main(String[] args)
    {
        new Person();
    }
}
//Person定义的初始化块:局部定量a的值大于4
//Person定义的初始化块
//Person定义的第二个初始化块
//Person类的无参构造函数

初始化块只在创建 Java 对象时隐式执行,而且在执行构造器之前执行。

使用 javac 命令编译 Java 类后,该 Java 类中的初始化块会消失,初始化块中代码会被“还原”到每个构造器中,且位于构造器前面

2、关联性

初始化块可以说是构造器的补充,初始化块总是在构造器执行之前执行的。与构造器不同的是,初始化块是一段固定的代码,它不能接收任何参数。因此初始化块对同一个类的所有对象所进行的初始化处理完全相同,利用这一点,我们可以将一段对所有对象完全相同,且无须接收任何参数的初始化处理代码提取到初始化块中,这样能更好地提高初始化代码的复用,提高整个应用的可维护性。
在这里插入图片描述

3、静态初始化块

如果定义初始化块时使用了 static 修饰符,则这个初始化块就变成了静态初始化块,也被称为类初始化块,可以对类进行初始化。静态初始化块是类相关的,系统将在类初始化阶段执行静态初始化块,而不是在创建对象是执行。因此静态初始化块总是比普通初始化块先执行。因为静态初始化块属于类的静态成员,同样需要遵循静态成员不能访问非静态成员的规则,所以不能访问实例变量和实例方法。

下面程序创建三个类:Root、Mid 和 Leaf,这三个类都提供了静态初始化块和普通初始化块,而且 Mid 类里还使用 this 调用重载的构造器,而 Leaf 使用 super 显式调用其父类指定的构造器

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("和小陈一起学Java");
        System.out.println("执行 Leaf 的构造器");
    }
}
public class Test
{
    public static void main(String[] args)
    {
        new Leaf();
        new Leaf();
    }
}

在这里插入图片描述
第一次创建一个 Leaf 对象时,因为系统中还不存在 Leaf 类,因此需要先加载并初始化 Leaf 类,初始化 Leaf 类时会先执行其顶层父类的静态初始化块,再执行其直接父类的静态初始化块,最后才执行 Leaf 本身的静态初始化块。一旦 Leaf 类初始化成功后,Leaf 类就在该虚拟机里将一直存在,因此第二次创建 Leaf 实例时无须再次对 Leaf 类进行初始化。

静态初始化块在以后编写 C3P0 数据连接池的工具类时会被运用到

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值