Java中的代码块

113 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解Java中的代码块,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan

Java中的代码块

文章目录

代码块:

在java中,用{}括起来的内容统称为代码块

一、普通代码块

也就是类中方法的方法体,普通代码块不能单独存在,
它必须紧跟在方法名的后面,而且通过方法名去调用方法体中的内容执行
语法格式:
	public class 类名 {
        [修饰符列表] 返回值类型 方法名(形式参数列表){
			//普通代码块
		}
    }
例子
public class Test {
    public static void main(String[] args) {
        //调用方法
        say();
    }

    private static void say() {
        //这里面的具体方法实现细节都是方法体
        System.out.println("该方法被调用了!");
    }
}
运行截图

image-20220315103023277

二、构造代码块

又叫实例语句块。在类中直接定义,没有任何前缀、后缀、修饰符的代码块

一个类中至少有一个构造方法,注意的是:构造代码块在类加载的时候并没有执行

而是在构造方法执行之前,自动执行构造代码块中的语句,这个特殊的点也被叫做“对象构建时机”
语法形式:
	public class 类名 {
        /**
         * 构造代码块
         * */

        {
            构造代码块
        }
    }
例子
public class Test {
    public static void main(String[] args) {
        //创建Test对象测试构造代码块与构造方法的执行顺序
        Test test01 = new Test();
        System.out.println("=====我是一个分界线========");
        Test test02 = new Test();
    }

    /**
     * 构造代码块
     * */

    {
        System.out.println("构造代码块执行!");
    }

    /**
     * 无参构造
     * */
    public Test() {
        System.out.println("Test对象被创建");
    }
}
运行截图

image-20220315100613075

三、静态代码块

1、语法格式:
	static {
		java语句;
		java语句;
	}
2、执行时机
	类加载时执行。并且'在main方法执行之前执行 且 只执行一次'
3、静态代码块一般是按照自上而下的顺序执行。
4、静态代码块的作用:
    	静态代码块这种语法机制实际上是一个特殊的时刻/时机
		这个时机叫做:类加载时机
    比如:
    	需要记录那个类在什么时候被加载到jvm中,这些记录日志信息的代码块就写到静态代码块中
例子
package com.blog;


import java.text.SimpleDateFormat;
import java.util.Date;

import static java.lang.Thread.sleep;

public class Test {

    //静态代码块
    static {
        //输出静态代码块执行时当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        System.out.println("静态代码块执行时当前时间"+sdf.format(new Date()));
        
        //执行后线程睡眠1秒,用于区分
        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //主方法入口
    public static void main(String[] args) {
        //输出main方法执行时当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        System.out.println("main方法执行时当前时间"+sdf.format(new Date()));
        
        //执行后线程睡眠1秒,用于区分
        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
运行截图

image-20220315102754941

四、同步代码块

使用 synchronized 关键字修饰,并使用“{}”括起来的代码片段,
它表示同一时间只能有一个线程进入到该方法块中,是一种多线程保护机制。
在多线程环境下,对共享数据的读写操作是需要互斥进行的,
否则会导致数据的不一致性。同步代码块需要写在方法中。
例子
package com.blog;


/**
 * @author 尽欢
 */
public class Test {
    public static void main(String[] args) {
        Demo demo01 = new Demo();
        //两个线程公用同一个对象(会出现抢占使用权限情况)
        Thread thread01 = new Thread(new MyTestThread(demo01), "线程a");
        Thread thread02 = new Thread(new MyTestThread(demo01), "线程b");
        thread01.start();
        thread02.start();
    }
}

class MyTestThread extends Thread {
    //创建一个Demo对象
    private Demo demo;

    /**
     * 构造方法
     * */
    public MyTestThread(Demo demo) {
        this.demo = demo;
    }

    public MyTestThread() {
    }

    /**
     * run方法入口
     * */
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //调用方法修改num的值
        numCheck();
    }

    public void numCheck() {
        synchronized (Demo.class) {
            //打印抢占成功的线程(此时各个线程抢占机会均等)
            System.out.println(Thread.currentThread().getName()+"开始执行:");
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (demo.num > 0) {
                    //打印num的值并更新
                    System.out.println(Thread.currentThread().getName() + ",此时num的值为:" + demo.num--);
                } else {
                    System.out.println(Thread.currentThread().getName() + "执行结束!");
                    break;
                }
            }
        }
    }
}

class Demo {
    public int num = 10;
}
运行截图

image-20220315105503868

image-20220315105547403

构造代码块以及静态代码块的执行顺序

普通代码块也就是方法:只有在通过方法名调用的时候才会执行
那么构造代码块以及静态代码块的执行顺序是怎样的呢?	
分析一下:(BB了半天,为什么不用流程图呢?上图)

流程图

在这里插入图片描述

例子
package com.blog;


/**
 * @author 尽欢
 */
/**
 * 父类Test
 * */
public class Test {

    /**
     * main方法入口
     * */
    public static void main(String[] args) {
        new LittleTest();
    }
    static {
        System.out.println("父类静态代码块执行!");
    }

    {
        System.out.println("父类构造代码块执行!");
    }

    public Test() {
        System.out.println("父类构造方法执行!");
    }
}
class LittleTest extends Test{
    static {
        System.out.println("子类静态代码块执行!");
    }

    {
        System.out.println("子类构造代码块执行!");
    }

    public LittleTest() {
        System.out.println("子类构造方法执行!");
    }
}
运行截图

image-20220315110844806

关于Java中的代码块的讲解就到这里了。最后别忘啦支持一下博主哦,求三连!❤️❤️❤️