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
女朋友钱不够,取不了

总结:

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

猜你喜欢

转载自blog.csdn.net/qq_43010602/article/details/122159454