Java:静态代码块(static关键字应用之一)、实例代码块(实例初始化块)

代码块是类的5大成分之一(成员变量、构造器、方法、代码块、内部类)。

代码块按照有无static修饰,分为两种:静态代码块(有static修饰)、实例代码块(没有static修饰,也叫实例初始化块)。

静态代码块

为什么需要静态代码块

通常,我们会在声明时直接初始化静态变量。然而,如果静态变量在初始化时需要多条语句的逻辑,我们可以使用静态代码块来代替。

总的来说,使用静态代码块的主要原因有:

  • 初始化静态变量时需要一些额外的逻辑,而不仅仅是赋值。
  • 用自定义异常处理来初始化静态变量。

静态代码块的格式

static {代码}

静态代码块的特点

静态代码块在类加载时自动执行,且只会执行一次。

静态代码块的作用

完成类的初始化,例如,类变量的初始化。

示例

示例:声明一个静态代码块

定义一个Student类:

package com.team.block.e1;

public class Student {
    static int number = 60;
    // 静态代码块
    static {
        System.out.println("Student中的静态代码块被执行了");
    }
}

定义测试类Test:

package com.team.block.e1;

public class Test {
    public static void main(String[] args) {
        System.out.println(Student.number);
    }
}

运行结果:
在这里插入图片描述

示例:演示静态代码块只会被执行一次

定义一个Student类:

package com.team.block.e1;

public class Student {
    static int number = 60;
    // 静态代码块
    static {
        System.out.println("Student中的静态代码块被执行了");
    }
}

定义测试类Test:

package com.team.block.e1;

public class Test {
    public static void main(String[] args) {
        System.out.println(Student.number);
        System.out.println(Student.number);
        System.out.println(Student.number);
    }
}

运行结果:
在这里插入图片描述

示例:利用静态代码块对类变量初始化

定义Student类:

package com.team.block.e1;

import java.util.ArrayList;

public class Student {
    static ArrayList<String> hobbies = new ArrayList<>();
    // 静态代码块
    static {
        System.out.println("Student中的静态代码块被执行了");
        hobbies.add("游泳");
        hobbies.add("跑步");
        hobbies.add("吃海鲜");
    }
}

定义测试类Test:

package com.team.block.e1;

public class Test {
    public static void main(String[] args) {
        System.out.println(Student.hobbies);
    }
}

运行结果:
在这里插入图片描述

示例:jdk中的java.net.Socket类利用静态代码块对类变量初始化

在这里插入图片描述

实例代码块(也叫实例初始化块)

实例代码块的格式

{代码}

实例代码块也称为实例初始化块,它是一段在类内部声明的代码,用于初始化实例数据成员。实例初始化块对每个对象只执行一次,可以用来为实例变量设置初始值。

实例初始化块与Java的构造器类似,但其执行和使用方式不同。

实例代码块的特点

  • 实例初始化块在对象创建时被调用一次。
  • 实例初始化块在任何对象的构造函数被调用之前执行。
  • 在子类的情况下,实例初始化块将在超类构造函数调用之后被调用。
  • 实例初始化块可用于执行多条语句。
  • 实例初始化块通常用于实例化多个值字段,如数组。

实例代码块的用途

以下是Java中实例初始化块的用途:

  • 用于初始化实例变量。
  • 用于初始化代码中使用的资源。
  • 用于执行实例变量的动态初始化。
  • 用于为多个构造器使用共同的初始化逻辑,减少构造器中重复代码的编写。

示例

示例:声明一个实例初始化块

创建一个Foo类:

package com.team.block.e2;

public class Foo {
    int a;
    {
        a = 10;
    }
}

创建一个测试类Test:

package com.team.block.e2;

public class Test {
    public static void main(String[] args) {
        Foo foo1 = new Foo();
        System.out.println(foo1.a);
    }
}

运行结果:
在这里插入图片描述

示例:演示实例初始化块和构造器的调用顺序

定义Foo类:

package com.team.block.e2;

public class Foo {
    {
        System.out.println("Foo的实例初始化块被调用了");
    }

    public Foo() {
        System.out.println("Foo的构造器被调用了");
    }
}

定义测试类Test:

package com.team.block.e2;

public class Test {
    public static void main(String[] args) {
        Foo foo1 = new Foo();
    }
}

运行结果:
在这里插入图片描述

示例:演示构造器是否覆盖实例初始化块

在这个例子中,我们展示了在实例初始化块中初始化的值被对象构造器覆盖了。当使用new操作符创建对象时,实例初始化块和构造函数都会被调用。

创建一个Foo类:

package com.team.block.e2;

public class Foo {
    int a;

    {
        System.out.println("Foo的实例初始化块被调用了");
        a = 10;
    }

    public Foo() {
        System.out.println("Foo的构造器被调用了");
        a = 20;
    }
}

创建一个测试类Test:

package com.team.block.e2;

public class Test {
    public static void main(String[] args) {
        Foo foo = new Foo();
        System.out.println(foo.a);
    }
}

运行结果:
在这里插入图片描述

示例:演示实例初始化块在每次生成一个对象的时候都会被执行一次

Foo类:

package com.team.block.e2;

public class Foo {
    int a;

    {
        System.out.println("Foo的实例初始化块被调用了");
    }

    public Foo() {
        System.out.println("Foo的构造器被调用了");
    }
}

测试类Test:

package com.team.block.e2;

public class Test {
    public static void main(String[] args) {
        Foo foo1 = new Foo();

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

        Foo foo2 = new Foo();
    }
}

运行结果:
在这里插入图片描述

示例:演示实例初始化块、无参构造器、有参构造器

类Foo:

package com.team.block.e2;

public class Foo {
    private int a;

    {
        System.out.println("Foo的实例初始化块被调用了");
    }

    // 无参构造器
    public Foo() {
        System.out.println("Foo的无参构造器被调用了");
    }

    // 有参构造器
    public Foo (int a) {
        System.out.println("Foo的有参构造器被调用了");
    }
}

测试类Test:

package com.team.block.e2;

public class Test {
    public static void main(String[] args) {
        Foo foo1 = new Foo();

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

        Foo foo2 = new Foo(10);
    }
}

运行结果:
在这里插入图片描述

示例:演示实例初始化块和父类构造器的执行顺序

在这个例子中,在输出中,可以验证被调用的代码块的顺序。首先调用父类的构造器,然后调用子类的实例初始化块,该块初始化一个实例变量,接着调用子类的构造器。

父类SuperFoo:

package com.team.block.e2;

public class SuperFoo {
    public SuperFoo() {
        System.out.println("SuperFoo的构造器被调用了");
    }
}

子类Foo:

package com.team.block.e2;

public class Foo extends SuperFoo {
    int a;

    {
        System.out.println("Foo的实例初始化块被调用了");
        a = 10;
    }

    public Foo() {
        System.out.println("Foo的构造器被调用了");
    }
}

测试类Test:

package com.team.block.e2;

public class Test {
    public static void main(String[] args) {
        Foo foo = new Foo();
        System.out.println("a的值是:" + foo.a);
    }
}

运行输出:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值