Java 代码块详解

导读:本篇文章讲解 Java 代码块详解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Java 代码块详解

基本介绍

代码块又称 初始化块, 是类的一部分,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过 {} 封装起来。
但是代码块没有方法名,没有返回,没有参数, 只有方法体,而且不用通过对象或类显示调用,而是加载类的时候,或创建对象的时候隐式调用。

基本语法

在这里插入图片描述

  1. 修饰符可选,并且修饰符只能为 static
  2. 代码块分为两类,用 static 修饰的为静态代码块,没有 static 修饰的为普通代码块
  3. 代码块中可以写任何语句(输入,输出,方法调用,循环,判断等等)。
  4. ; 可以省略。

代码块示例

student类

public class Student {
    private int id;
    private String name;
    private int age;

    {
        System.out.println("代码块被执行~~");
    }

    public Student(int id, String name, int age) {
        System.out.println("构造器被调用~~~");
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

BlockCodeTest类

public class BlockCodeTest {
//    代码块调用的顺序优先于构造器
    public static void main(String[] args) {
        Student s = new Student(1, "王昭君", 18);
    }
}

运行结果:
在这里插入图片描述
通过运行结果我们发现,代码块调用的顺序优先于构造器的,所以,代码块相当于另外一种形式的构造器,可以作为构造器的补充机制,做初始化的操作。

代码块使用细节

1. static代码块也叫静态代码块,作用就是对类进行初始化,它随类加载而执行,并且只会执行一次。如果是普通代码块(非静态代码块),每创建一个对象执行一次。

🚀类加载时机 非常重要

1.创建实例对象时(new)
2.创建子类对象实例时,父类也会被加载
3.使用类的静态成员时(静态属性、静态方法)

代码示例1 【创建实例对象时(new)】

public class BlockCodeTest {
    public static void main(String[] args) {
        A a = new A();
    }
}

class A {
    static {
        System.out.println("静态代码块被执行~~~");
    }
}

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

代码示例2 【创建子类对象实例时,父类也会被加载】

public class BlockCodeTest {
    public static void main(String[] args) {
        B b = new B();
    }
}

class A {
    static {
        System.out.println("A类静态代码块执行~~~");
    }
}

class B extends A {
    static {
        System.out.println("B类静态代码块执行~~~");
    }
}

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

在实例化B类的对象时,其父类A类也被加载,并且父类加载先于子类。

代码示例3 【使用类的静态成员时】

public class BlockCodeTest {
    public static void main(String[] args) {
        System.out.println(A.num);
    }
}

class A {
    public static int num = 1;
    static {
        System.out.println("A静态代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
调用静态变量,触发类加载,调用了A类的静态代码块。

代码示例4 【静态代码块在类加载时执行,并且只会执行一次】

public class BlockCodeTest {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
    }
}

class A {
    public static int num = 1;
    static {
        System.out.println("A静态代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
static代码块, 是在类加载时执行的, 而且只会执行一次。

2. 普通的代码块,在创建对象实例时,会被隐式调用,被创建一次,就会被调动一次。
可以理解为在用类的构造器实例化对象的时候,构造器中有自动调用普通代码块机制。如果只是使用类的静态成员时,普通代码块并不会执行。
在这里插入图片描述

代码示例1

public class BlockCodeTest {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
        A a3 = new A();
    }
}

class A {
    {
        System.out.println("A普通代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
实例化了3个对象,普通代码块执行了3次。

代码示例2

public class BlockCodeTest {
    public static void main(String[] args) {
        System.out.println(A.num);
    }
}

class A {
    public static int num = 1;
    {
        System.out.println("A普通代码块执行~~~");
    }
    static {
        System.out.println("A静态代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
使用类的静态成员,普通代码块并不会执行。

🚀小结:

1.static代码块是在类加载时执行的,并且只会执行一次。
2.普通代码块是在创建对象的时候调用的,与类加载无关,创建一次对象,调用一次。

3. 创建一个对象时,在一个类中的调用顺序:
1) 调用静态代码块和静态属性的初始化(静态代码块和静态属性的初始化调用的优先级一样,如果有多个静态代码块和多个静态属性初始化,则按照他们的定义顺序调用)
2) 调用普通代码块和普通属性的初始化(普通代码块和普通属性的初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按照他们定义的顺序调用)
3)最后调用构造方法

代码示例

public class BlockCodeTest {
    public static void main(String[] args) {
        A a = new A();
    }
}

class A {
    //静态属性
    private static int num1 = getVal1();
    //普通属性
    private int num2 = getVal2();

    public A() {
        System.out.println("构造器被执行...");
    }
    //静态代码块
    static {
        System.out.println("A静态代码块儿执行~~");
    }

    //普通代码块
    {
        System.out.println("A普通代码块儿执行");
    }

    public static int getVal1() {
        System.out.println("getVal1执行...");
        return 1;
    }

    public int getVal2() {
        System.out.println("getVal2执行...");
        return 2;
    }
}

运行结果:
在这里插入图片描述
实例化一个A对象,首先产生类加载,完成静态属性的初始化和执行静态代码块(静态代码块和静态属性的初始化调用的优先级一样,因为A类中静态属性的初始化在静态代码块的前面,所以先完成静态属性的初始化),之后执行构造器,因为构造器中有自动调用普通代码块机制和初始化普通属性的机制,所以先完成普通属性的初始化和执行普通代码块(当然这里也没有优先级),最后执行构造器中的代码。

4. 构造器的前面其实隐藏了super() 调用普通代码块

在这里插入图片描述
代码示例

public class BlockCodeTest {
    public static void main(String[] args) {
        B b = new B();
    }
}

class A {
    {
        System.out.println("A类的普通代码块被执行...");
    }

    public A() {
        //super()
        //调用普通代码块
        System.out.println("A类的构造器被调用...");
    }
}

class B extends A {
    {
        System.out.println("B类的普通代码块被执行...");
    }

    public B() {
        //super()
        //调用本类的代码块
        System.out.println("B类的构造器被调用...");
    }
}

运行结果:
在这里插入图片描述
调用B类构造器的时候,因为构造器中有隐含的super()和调用本类的普通代码块,所以,先执行其父类A类的构造器,其A类同时也有隐含的super()和调用本类的普通代码块,其父类为object,没有相关操作,最后执行结果如上。

5. 有继承关系时,他们的 静态代码块静态属性的初始化 普通属性的初始化 普通代码块 构造方法的调用顺序如下:
父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
父类的普通代码块和普通属性 (优先级一样,按定义顺序执行)
父类的构造方法
子类的普通代码块和普通属性 (优先级一样,按定义顺序执行)
子类的构造方法

代码示例

public class BlockCodeTest {
    public static void main(String[] args) {
        B b = new B();
    }
}

class A {
    private static int num1 = getVal1();
    private int num2 = getVal2();

    {
        System.out.println("A类的普通代码块被执行...");
    }

    static {
        System.out.println("A类的静态代码块被执行...");
    }

    public A() {
        System.out.println("A类构造器被执行");
    }

    public static int getVal1() {
        System.out.println("A类静态属性初始化...");
        return 1;
    }

    public int getVal2() {
        System.out.println("A类普通属性初始化...");
        return 2;
    }
}

class B extends A {
    private static int num1 = getVal11();
    private int num2 = getVal22();

    {
        System.out.println("B类的普通代码块被执行...");
    }

    static {
        System.out.println("B类的静态代码块被执行...");
    }

    public B() {
        System.out.println("B类构造器被执行");
    }

    public static int getVal11() {
        System.out.println("B类静态属性初始化...");
        return 1;
    }

    public int getVal22() {
        System.out.println("B类普通属性初始化...");
        return 2;
    }
}

运行结果:
在这里插入图片描述
6. 静态代码块只能调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/95515.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!