• Java - 代码块


    概述

    Java 中用 {} 括起来的代码形式叫做代码块。分为 4 种代码块,分别是:

    1、普通代码块

    定义在 方法中,方法调用时被执行

    public static void main(String[] args) {
        {
            System.out.println("普通代码块1");
        }
        System.out.println("main 方法");
        {
            System.out.println("普通代码块2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输出:

    普通代码块1
    main 方法
    普通代码块2
    
    • 1
    • 2
    • 3

    可以看出,普通代码块的执行顺序就是出现在代码中的顺序,一般用于把一种业务相关的代码给括起来,提高代码可读性

    2、构造代码块

    直接在 类中 定义,创建对象时被调用,每次创建对象都会被调用,并且调用时机优先于构造函数,如果存在多个,执行顺序就是出现的顺序。接下来分别验证这些说法:


    验证一

    public class CodeBlock {
    
        {
            System.out.println("构造代码块1");
        }
    
    	public CodeBlock1() {
            System.out.println("构造函数");
        }
    
        public static void main(String[] args) {
            System.out.println("main 方法");
        }
    
        {
            System.out.println("构造代码块2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    上面代码中,只会输出一个 main 方法,因为没有创建对象,所有构造函数和构造代码块都不会执行。


    验证二

    public class CodeBlock1 {
    
        {
            System.out.println("构造代码块1");
        }
    
        public CodeBlock1() {
            System.out.println("构造函数");
        }
    
        public static void main(String[] args) {
            CodeBlock1 codeBlock1 = new CodeBlock1();
            System.out.println("main 方法");
        }
    
        {
            System.out.println("构造代码块2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出:

    构造代码块1
    构造代码块2
    构造函数
    main 方法
    
    • 1
    • 2
    • 3
    • 4

    代码块的执行顺序优先于构造函数,并且多个代码块的执行顺序是按照出现在代码中的顺序


    验证三

    public class CodeBlock1 {
    
        {
            System.out.println("构造代码块1");
        }
    
        public CodeBlock1() {
            System.out.println("构造函数");
        }
    
        public static void main(String[] args) {
            CodeBlock1 codeBlock1 = new CodeBlock1();
            System.out.println("main 方法");
            CodeBlock1 codeBlock2 = new CodeBlock1();
        }
    
        {
            System.out.println("构造代码块2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    输出:

    构造代码块1
    构造代码块2
    构造函数
    main 方法
    构造代码块1
    构造代码块2
    构造函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    从结果可以看出来,构造代码块的伴随着对象的创建而执行,每一次创建对象都会执行

    3、静态代码块

    static 关键字进行修饰的代码块,用于初始化类的,为类的属性进行初始化。每个静态代码块只会执行一次,并且是由于 JVM 在加载类的时候就会执行静态代码块,所以静态代码块也会优先于 main 方法 执行。如果类中包含多个静态代码块,执行顺序也是类中出现的顺序。

    public class CodeBlock2 {
    
        private static int i;
    
        static {
            i = 10;
            System.out.println("静态代码块1");
        }
    
        public CodeBlock2() {
            System.out.println("构造函数");
        }
    
        public static void main(String[] args) {
            System.out.println("main 方法");
        }
    
        static {
            System.out.println("静态代码块2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    输出:

    静态代码块1
    静态代码块2
    main 方法
    
    • 1
    • 2
    • 3

    可以看到,静态代码块是优先于 main 方法 执行的,而且执行顺序也是类中出现的顺序。


    public class CodeBlock2 {
    
        private static int i;
    
        static {
            i = 10;
            System.out.println("静态代码块1");
        }
    
        public CodeBlock2() {
            System.out.println("构造函数");
        }
    
        public static void main(String[] args) {
            CodeBlock2 codeBlock1 = new CodeBlock2();
            System.out.println("main 方法");
            CodeBlock2 codeBlock2 = new CodeBlock2();
        }
    
        static {
            System.out.println("静态代码块2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    输出:

    静态代码块1
    静态代码块2
    构造函数
    main 方法
    构造函数
    
    • 1
    • 2
    • 3
    • 4
    • 5

    从结果可以看到,静态代码块只在类加载的时候执行一次。

    注意

    1. 静态代码块不能存在于任何方法体内,因为静态代码块只会在类加载的时候初始化一次
    2. 静态代码块不能直接访问实例的变量和方法,因为静态代码块加载的时候,实例还没有创建

    4、同步代码块

    使用 synchronized 关键字修饰的代码块,在多线程环境下,对共享数据的读写操作需要进行互斥保护,否则会导致数据不一致。同步代码块需要写在方法中。

    public class CodeBlock3 {
    
        private static final Object object = new Object();
    
        public static void main(String[] args) {
            System.out.println("main 方法");
    
            synchronized (object) {
    
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    总结

    public class CodeBlock5 {
    
        private static int i;
    
        static {
            i = 10;
            System.out.println("静态代码块,类加载的时候执行");
        }
    
        {
            System.out.println("构造代码块,优先于构造函数执行");
        }
    
        public CodeBlock5() {
            System.out.println("构造函数,创建对象的时候执行");
        }
    
        public static void main(String[] args) {
            CodeBlock5 codeBlock1 = new CodeBlock5();
            codeBlock1.fun1();
            System.out.println("main 方法");
            CodeBlock5.fun2();
        }
    
        public void fun1() {
        	// 这里的 {} 可以省略
            {
                System.out.println("实例对象的方法,方法被调用时执行");
            }
        }
    
        public static void fun2() {
            {
                System.out.println("类的方法,方法被调用时执行,晚于静态代码块执行");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    输出:

    静态代码块,类加载的时候执行
    构造代码块,优先于构造函数执行
    构造函数,创建对象的时候执行
    实例对象的方法,方法被调用时执行
    main 方法
    类的方法,方法被调用时执行,晚于静态代码块执行
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    AI工人操作行为流程规范识别算法
    新一代信息技术与制造业融合发展背景下网络安全挑战和思考
    C++ Reference: Standard C++ Library reference: C Library: cmath: sinh
    Java中该如何面向对象以及类的定义、使用和实例化
    【JavaSE】数据类型与变量
    MyBatis 动态 SQL、MyBatis 标签、MyBatis关联查询
    (附源码)springboot教学评价 毕业设计 641310
    Webpack
    java毕业设计校园资料在线分享网站mybatis+源码+调试部署+系统+数据库+lw
    【C++入门系列】——类和对象
  • 原文地址:https://blog.csdn.net/qiaohao0206/article/details/126278682