JAVA四种代码块总结

一、四种代码块

  在java中用 { } 包裹起来的代码片段称为代码块,一共有以下4种:
在这里插入图片描述

二、普通代码块

示例代码:

public class CommonBlock {
  public static void main(String[] args) {
    //普通代码块:定义在方法内
    {
      String commonBlock = "执行普通代码块1";
      System.out.println(commonBlock);
    }

    String main = "执行main方法";
    System.out.println(main);

    {
      String commonBlock = "执行普通代码块2,变量名同普通代码块1";
      System.out.println(commonBlock);
    }
  }
}

运行结果:

执行普通代码块1
执行main方法
执行普通代码块2,变量名同普通代码块1

总结

普通代码块和一般语句的执行顺序由编写顺序决定

三、构造代码块

示例代码:

public class ConstructionBlock {
  {
    String constructionBlock = "构造代码块1";
    System.out.println(constructionBlock);
  }

  public ConstructionBlock(int i) {
    System.out.println("第" + i + "次调用构造方法");
  }

  {
    String constructionBlock = "构造代码块2";
    System.out.println(constructionBlock);
  }

  public static void main(String[] args) {
    new ConstructionBlock(1);
    System.out.println("==============");
    new ConstructionBlock(2);
    System.out.println("==============");
    new ConstructionBlock(3);
  }
}

执行结果:

构造代码块1
构造代码块2
第2次调用构造方法
==============
构造代码块1
构造代码块2
第3次调用构造方法

总结:

1.每次创建对象都会被调用,构造代码块优先级高于构造函数;
2.存在多个构造代码块时,执行顺序由编写顺序决定。

四、静态代码块

示例代码:

public class StaticBlock {
  static {
    System.out.println("执行静态代码块1");
  }

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

  public StaticBlock(int i) {
    System.out.println("第"+i+"次调用构造函数");
  }

  public static void main(String[] args) {
    new StaticBlock(1);
    System.out.println("==================");
    new StaticBlock(2);
  }

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

  static {
    System.out.println("执行静态代码块2");
  }
}

执行结果:

执行静态代码块1
执行静态代码块2
执行构造代码块1
执行构造代码块2
第1次调用构造函数
==================
执行构造代码块1
执行构造代码块2
第2次调用构造函数

总结:

1.静态代码块只会执行一次,静态代码块优先级高于主方法;
2.存在多个静态代码块时,执行顺序由编写顺序决定。

五、综合

示例代码:

public class TogetherBlock {

  //静态代码块:定义在类中,只执行一次
  static {
    System.out.println("静态代码块");
  }

  //构造代码块:定义在类中,每次实例化对象都会执行
  {
    System.out.println("构造代码块");
  }

  //构造方法:每次实例化都会调用
  public TogetherBlock() {
    System.out.println("调用了构造方法");
  }

  public void commonMethod() {
    //普通代码块:定义在方法中,调用方法时执行
    {
      System.out.println("普通方法中的普通代码块");
    }
  }

  public static void staticCommonMethod() {
    {
      System.out.println("静态方法中的普通代码块");
    }
  }

  public static void main(String[] args) {
    new TogetherBlock().commonMethod();
    new TogetherBlock().commonMethod();
    System.out.println("======================");
    TogetherBlock.staticCommonMethod();
    TogetherBlock.staticCommonMethod();
  }
}

执行结果:

静态代码块
构造代码块
调用了构造方法
普通方法中的普通代码块
构造代码块
调用了构造方法
普通方法中的普通代码块
======================
静态方法中的普通代码块
静态方法中的普通代码块

总结:

1.静态代码块总是最先执行,并且只有在创建对象的第一个实例时才会被执行一次;
2.构造代码块其后执行,并且创建一次对象实例的时候就被执行一次;
3.构造方法其后执行,并且创建一次对象实例的时候就被执行一次;
3.普通代码块在方法被调用时执行。

六、同步代码块

示例代码:

//不安全的取钱
//两个人去银行取钱,账户
public class SynBlock {
  public static void main(String[] args) {
    //账户
    Account account = new Account(100,"结婚基金");

    Withdraw you = new Withdraw(account,50,"你");
    Withdraw girlfriend = new Withdraw(account,100,"女朋友");

    you.start();
    girlfriend.start();
  }
}

//账户
class Account{
  int money;//余额
  String name;//卡号

  public Account(int money, String name) {
    this.money = money;
    this.name = name;
  }
}

//银行:模拟取款
class Withdraw extends Thread{
  Account account;//账户
  int withdrawMoney;//取多少钱
  int nowMoney;//现在手里有多少钱

  public Withdraw(Account account,int withdrawMoney,String name){
    super(name);
    this.account = account;
    this.withdrawMoney = withdrawMoney;
  }
  //取钱
  //synchronized默认锁的是this
  @Override
  public void run() {
    synchronized (account){
      //判断有没有钱
      if (account.money - withdrawMoney < 0){
        System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
        return;
      }
      //sleep可以放大问题的发生性
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      //卡内余额 = 余额 - 你取的钱;
      account.money = account.money - withdrawMoney;
      //你手里的钱
      nowMoney = nowMoney + withdrawMoney;

      System.out.println(account.name+"余额为:"+account.money);
      //Thread.currentThread().getName() == this.getName()
      //Withdraw继承Thread,Thread有getName()方法
      System.out.println(this.getName()+"手里的钱"+nowMoney);
    }
  }
}

执行结果:

结婚基金余额为:50
你手里的钱50
女朋友钱不够,取不了

总结:

多个进程访问同一资源是保证只有一个线程能执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值