代码块

基本概念与用法

代码块又叫做初始化块,属于类的成员,是类的一部分,类似于方法,把逻辑方庄在方法体中,通过{}包围起来。和方法不同,没有方法名,没有返回,没有参数,只有方法体,且不能通过对象或类显式调用。而是加载类,或创建对象时隐式调用。

基本语法:[修饰符]{代码};

  1. 修饰符可写同时只能写static
  2. 代码块分静态代码块和非静态代码块。
  3. 逻辑语句可以为任何逻辑语句,包括输入输出,方法调用,循环,判断等
  4.  ;可以不写
public class BlockDemo {
    public static void main(String[] args) {
        Movie movie = new Movie("功夫");
        Movie movie1 = new Movie("食神",200,"周星驰");

    }
}
class Movie{
    private String name;
    private double price;
    private String director;

    {
        // 调用任意一个构造器都会先执行代码块内的代码
        System.out.println("广告加载中。。。");
        System.out.println("广告倒计时10S。。。");
        System.out.println("正在跳过广告。。。");
    }
    public Movie(String name) {
       /* System.out.println("广告加载中。。。");
        System.out.println("广告倒计时10S。。。");
        System.out.println("正在跳过广告。。。");*/
        System.out.println("Movie(String name)被调用,电影开始播放");
        this.name = name;
    }

    public Movie(double price, String director) {
        /* System.out.println("广告加载中。。。");
        System.out.println("广告倒计时10S。。。");
        System.out.println("正在跳过广告。。。");*/
        this.price = price;
        this.director = director;
    }

    public Movie(String name, double price, String director) {
        /* System.out.println("广告加载中。。。");
        System.out.println("广告倒计时10S。。。");
        System.out.println("正在跳过广告。。。");*/
        System.out.println("Movie(String name, double price, String director)被调用,电影开始播放");
        this.name = name;
        this.price = price;
        this.director = director;
    }
}

代码块相当于对构造器的一种补充功能,可以做初始化操作,当构造器有重复语句时可以提取到代码块中,提高代码的重用性

static代码块也叫静态代码块,作用是对类的初始化,而且随着类的加载而执行且只执行一次。如果是普通代码块,每次创建对象都会执行一次。

类加载的时间:

  1. 当对象实例化时(new)
  2. 创建子类对象实例,父类也会被加载
  3. 使用静态成员时

普通代码块在创建对象时,会被隐式调用,创建一次就调用一次如果是使用静态成员,普通代码块就不会执行。

public class BlockDemo {
    public static void main(String[] args) {
        A a = new A();  // 父类的代码块先输出子类的后输出。
        System.out.println("输出了"+C.str);
        D d1 = new D();
        D d2 = new D();
        System.out.println(D.strD);

    }
}

class A extends B{

    static {
        System.out.println("A类的静态代码块被执行");
    }
}
class B{
    static {
        System.out.println("B类的静态代码块被执行");
    }
}
class C{
    public static String str="C类的静态属性";
    static {
        System.out.println("C类的静态代码块被执行");
    }
}
class D{
    public static String strD="D类的静态属性";
    static {
        System.out.println("D类的静态代码块被执行");
    }
    {
        System.out.println("D类代码块被执行");
    }
}

 小结:static代码块是类加载时被调用且只执行一次,普通代码块只有创建对象时被调用。

调用顺序

创建一个对象时,在一个类的调用顺序是:

第一步:调用静态代码块和静态属性初始化;

静态代码与静态属性初始化调用的优先级一样,

如果有多个静态代码块和多个静态变量初始化根据定义顺序调用

第二步:调用普通代码块和普通属性的初始化;

普通代码块和普通属性初始化调用的优先级一样,

如果有多个普通代码块和多个普通属性初始化,按定义顺序调用。

 第三步:执行构造器

public class BlockDemo {
    public static void main(String[] args) {
        A a = new A();

    }
}
class A{
   

    private static int num1=getNum1();
    private  int num2=getNum2();
    public A(){
        System.out.println("无参构造器");
    }
    {
        System.out.println("普通代码块1");
    }
    static {
        System.out.println("静态代码块1");
    }
    public static int getNum1(){
        System.out.println("getNum1被调用");
        return 100;
    }

    public  int getNum2() {
        System.out.println("getNum2被调用");
        return 200;
    }
}

 构造器的最前面隐藏了super()和调用普通代码块,静态相关代码块,属性初始化,在类加载是完成,所以优先于构造器和普通代码块的执行。

public class BlockDemo {
    public static void main(String[] args) {
        B b = new B();

    }
}
class A{

    public A(){
        System.out.println("A类的无参构造器");
    }
    {
        System.out.println("A类的普通代码块");
    }
    static {
        System.out.println("A类的静态代码块");
    }

}
class B extends A{
    {
        System.out.println("B类的普通代码块");
    }
    public B() {

        System.out.println("B类的无参构造器");
    }
}
posted @ 2024-04-03 23:35  Dr丶云幕  阅读(37)  评论(0编辑  收藏  举报