Java中的代码块
代码块:
在java中,用{}括起来的内容统称为代码块
一、普通代码块
也就是类中方法的方法体,普通代码块不能单独存在,
它必须紧跟在方法名的后面,而且通过方法名去调用方法体中的内容执行
语法格式:
public class 类名 {
[修饰符列表] 返回值类型 方法名(形式参数列表){
}
}
例子
public class Test {
public static void main(String[] args) {
say();
}
private static void say() {
System.out.println("该方法被调用了!");
}
}
运行截图
二、构造代码块
又叫实例语句块。在类中直接定义,没有任何前缀、后缀、修饰符的代码块
一个类中至少有一个构造方法,注意的是:构造代码块在类加载的时候并没有执行
而是在构造方法执行之前,自动执行构造代码块中的语句,这个特殊的点也被叫做“对象构建时机”
语法形式:
public class 类名 {
{
构造代码块
}
}
例子
public class Test {
public static void main(String[] args) {
Test test01 = new Test();
System.out.println("=====我是一个分界线========");
Test test02 = new Test();
}
{
System.out.println("构造代码块执行!");
}
public Test() {
System.out.println("Test对象被创建");
}
}
运行截图
三、静态代码块
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()));
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println("main方法执行时当前时间"+sdf.format(new Date()));
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行截图
四、同步代码块
使用 synchronized 关键字修饰,并使用“{}”括起来的代码片段,
它表示同一时间只能有一个线程进入到该方法块中,是一种多线程保护机制。
在多线程环境下,对共享数据的读写操作是需要互斥进行的,
否则会导致数据的不一致性。同步代码块需要写在方法中。
例子
package com.blog;
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 {
private Demo demo;
public MyTestThread(Demo demo) {
this.demo = demo;
}
public MyTestThread() {
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
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) {
System.out.println(Thread.currentThread().getName() + ",此时num的值为:" + demo.num--);
} else {
System.out.println(Thread.currentThread().getName() + "执行结束!");
break;
}
}
}
}
}
class Demo {
public int num = 10;
}
运行截图
构造代码块以及静态代码块的执行顺序
普通代码块也就是方法:只有在通过方法名调用的时候才会执行
那么构造代码块以及静态代码块的执行顺序是怎样的呢?
分析一下:(BB了半天,为什么不用流程图呢?上图)
流程图
例子
package com.blog;
public class Test {
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("子类构造方法执行!");
}
}
运行截图
|