Java代码块详解

代码块

  1. 代码块和方法不同,没有方法名,没有返回值,没有参数,只有方法体,而且不用通过对象或类的显示调用,而是加载类时,或创建对象时隐式调用

  2. 当子类继承了父类时,他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:

    加载顺序为:
    ​
    1.首先加载父类的静态字段或者静态语句块
    ​
    2.子类的静态字段或静态语句块
    ​
    3.父类普通变量以及语句块
    ​
    4.父类构造方法被加载
    ​
    5.子类变量或者语句块被加载
    ​
    6.子类构造方法被加载

  3. 代码块的好处:

    1. 相当于另一种形式的构造器(对构造器的补充机制),可以做初始化的操作

    2. 如果多个构造器都有重复的语句时,可以抽取到代码块中,提高代码的重用性

    3. 代码块的优先级是高于构造器的

    4. 案例:

      public class CodeBlock {
          public static void main(String[] args) {
              Movie movie = new Movie("你好,李焕英");
      
              Movie movie1 = new Movie("唐人街探案", 39.9);
      
          }
      }
      
      class Movie {
          private String name;
          private String time;
          private double price;
      
          // 下面三个构造器都使用和相同的语句 比较冗余
          // 这时候我们就可以把相同的语句放入代码块
          // 这样 当我们不管调用哪个构造器创建对象的时候 都会先调用代码块的内容
          // 代码块的调用是优先于构造器的
          {
              System.out.println("打开屏幕");
              System.out.println("广告开始");
          }
          public Movie() {
              // System.out.println("打开屏幕");
              // System.out.println("广告开始");
          }
          public Movie(String name) {
              // System.out.println("打开屏幕");
              // System.out.println("广告开始");
              System.out.println("String name被调用");
              this.name = name;
          }
          public Movie(String name, double price) {
              // System.out.println("打开屏幕");
              // System.out.println("广告开始");
              this.name = name;
              this.price = price;
          }
      }
      
      

  4. 代码块的使用细节:

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

    2. 类什么时候加载(三种情况)

      • 创建对象实例时(new)

      • 创建子类对象实例,父类也会被加载

      • 使用类的静态成员时(静态属性、静态方法)

        public class CodeBlock02 {
            public static void main(String[] args) {
                /*
                 * 类什么时候加载
                 */
                // 1.创建对象实例时(new)
                // Aa aa = new Aa();
        ​
                // 2.创建子类对象实例,父类也会被加载 而且父类先被加载 子类后加载
                // 继承是先加载父类再加载子类
                // Bb bb = new Bb();
        ​
                // 3.使用类的静态成员时(静态属性、静态方法)
                System.out.println(Cat.age);
            }
        }
        ​
        class Cat {
            public static int age = 10;
        ​
            static {
                System.out.println("这是Cat类的静态代码块");
            }
        }
        ​
        class Aa {
            // 静态代码块
            static {
                System.out.println("这是AA的静态代码块");
            }
        }
        ​
        class Bb extends Aa {
            static {
                System.out.println("这是BB的静态代码块");
            }
        }

    3. 普通代码块,在创建对象实例时,会被隐式的调用,对象被创建(new)一次,就会调用一次。

      如果只是使用类的静态成员时,因为没有创建对象(new),所以 普通代码块并不会被执行

    4. 可以这样简单理解:普通代码块就是构造器的补充

  5. 创建一个对象时,在一个类 调用顺序时:

    1. 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)

      public class CodeBlock03 {
          public static void main(String[] args) {
              Aaa aaa = new Aaa();// 输出 :1.getN1()被调用   2.这是Aaa类的静态代码块
      
          }
      }
      
      class Aaa {
          // 静态属性初始化
          private static int n1 = getN1();
      
          // 静态代码块
          static {
              System.out.println("这是Aaa类的静态代码块");
          }
      
          public static int getN1() {
              System.out.println("getN1()被调用");
              return 100;
          }
      }

    2. 调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)

    3. 调用构造方法

  6. 构造器的最前面其实隐含了super()和普通代码块。静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此是优先于 构造器和普通代码块执行的

    public class CodeBlock04 {
        public static void main(String[] args) {
            BBB bbb = new BBB();
        }
    }
    class AAA {
        {
            System.out.println("AAA的普通代码块");
        }
        public AAA() {
            // 这里有一个隐藏的执行要求
            // 1.super()
            // 2.调用普通代码块的
            super();
            // 隐藏:调用本类的普通代码块
            System.out.println("AAA的无参构造器");
        }
    }
    class BBB extends AAA {
        {
            System.out.println("BBB的普通代码块");
        }
        public BBB() {
            super();
            // 隐藏:调用本类的普通代码块
            System.out.println("BBB的无参构造器");
        }

你可能感兴趣的:(Java基础,java)