• 非零基础自学Java (老师:韩顺平) 第10章 面向对象编程(高级部分) 10.3 代码块


    非零基础自学Java (老师:韩顺平)

    ✈【【零基础 快速学Java】韩顺平 零基础30天学会Java】

    第10章 面向对象编程(高级部分)

    10.3 代码块
    10.3.1 基本介绍

    代码化块又称为初始化块,属于类中的成员[即是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过0包围起来。

    但是和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或者类显示调用,而是加载类或创建对象时隐式调用。

    10.3.2 基本语法
    [修饰符]{
        代码
    };
    
    • 1
    • 2
    • 3

    说明:

    • 修饰符可选,要写也只能写 static
    • 代码块分为两类,使用static修饰的叫静态代码块,没有static修饰的,叫普通代码块/非静态代码块。
    • 逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)
    • ; 号可写可不写
    10.3.3 代码块的好处和案例演示

    韩老师的理解:

    • 相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作
    • 场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性

    举个栗子

    package com.dingjiaxiong.codeblock_;
    
    /**
     * ClassName: CodeBlock01
     * date: 2022/9/3 16:50
     *
     * @author DingJiaxiong
     */
    
    public class CodeBlock01 {
        public static void main(String[] args) {
            Movie movie = new Movie("你好,李焕英");
            System.out.println("======================");
            Movie movie2 = new Movie("唐探3",100,"陈思诚");
        }
    }
    
    class Movie{
        private String name;
        private double price;
        private String director;
    
        {
            System.out.println("电影屏幕打开...");
            System.out.println("广告开始...");
            System.out.println("电影正式开始...");
        };
    
        public Movie(String name) {
            System.out.println("Movie(String name)被调用 ...");
            this.name = name;
        }
    
        public Movie(String name, double price) {
            System.out.println("Movie(String name, double price)被调用...");
            this.name = name;
            this.price = price;
        }
    
        public Movie(String name, double price, String director) {
            System.out.println("Movie(String name, double price, String director)被调用...");
            this.name = name;
            this.price = price;
            this.director = director;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    运行结果

    在这里插入图片描述

    10.3.4 代码块使用注意事项和细节讨论
    • static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行。
    • 类什么时候被加载【背!】
      • 创建对象实例时(new)
      • 创建子类对象实例,父类也会被加载
      • 使用类的静态成员时(静态属性,静态方法)
    • 普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。如果只是使用类的静态成员时,普通代码块并不会执行。

    小结:

    1. static代码块是类加载时执行,只会执行一次
    2. 普通代码块是在创建对象时调用的,创建一次,调用一次
    3. 类加载的3种情况,背!

    举个栗子

    package com.dingjiaxiong.codeblock_;
    
    /**
     * ClassName: CodeBlockDetail01
     * date: 2022/9/3 17:03
     *
     * @author DingJiaxiong
     */
    
    public class CodeBlockDetail01 {
        public static void main(String[] args) {
            //创建对象实例
            AA aa = new AA();
            //创建子类对象实例,父类也会被加载,而且父类先被加载
            AA aa2 = new AA();
    
            //使用类的静态成员
            System.out.println(Cat.n1);
    
            //static代码块,是在类加载时,执行的,而且只会执行一次。
            DD dd = new DD();
            DD dd1 = new DD();
    
            System.out.println(DD.n1); //静态模块一定会执行
        }
    }
    
    class DD{
        public static int n1 = 8888; //静态属性
        //静态代码块
        static {
            System.out.println("DD的静态代码块1被执行");
        }
        //普通代码块,在 new 对象时,被调用,而且是每创建一个对象,就调用一次
        {
            System.out.println("DD的普通代码块...");
        }
    }
    
    class Animal{
        //静态代码块
        static {
            System.out.println("Animal的静态代码1被执行...");
        }
    }
    
    class Cat extends Animal{
        public static int n1 = 999;//静态属性
        //静态代码块
        static {
            System.out.println("Cat的静态代码1被执行...");
        }
    }
    
    class BB{
        //静态代码块
        static {
            System.out.println("BB的静态代码块1被执行");
        }
    }
    
    class AA extends BB{
        static {
            System.out.println("AA的静态代码1被执行");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    运行结果

    在这里插入图片描述

    【创建一个对象时,在一个类中的调用顺序】

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

    举个栗子

    package com.dingjiaxiong.codeblock_;
    
    /**
     * ClassName: CodeBlockDetail02
     * date: 2022/9/3 17:17
     *
     * @author DingJiaxiong
     */
    
    public class CodeBlockDetail02 {
        public static void main(String[] args) {
            A a = new A();
        }
    }
    
    class A{
        //普通代码块
        {
            System.out.println("A 普通代码块01");
        }
    
        //普通属性的初始化
        private int n2 = getN2();
    
        //静态代码块
        static {
            System.out.println("A 静态代码块01");
        }
    
        //静态属性的初始化
        private static int n1 = getN1();
    
        public static int getN1(){
            System.out.println("getN1被调用");
            return 100;
        }
    
        public static int getN2(){
            System.out.println("getN2被调用");
            return 200;
        }
    
        //无参构造器
        public A(){
            System.out.println("A() 构造器被调用");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    运行结果

    在这里插入图片描述

    【构造器的最前面其实隐含了super()和调用普通代码块】

    举个栗子

    package com.dingjiaxiong.codeblock_;
    
    /**
     * ClassName: CodeBlockDetail03
     * date: 2022/9/3 17:23
     *
     * @author DingJiaxiong
     */
    
    public class CodeBlockDetail03 {
        public static void main(String[] args) {
            new BBB();
        }
    }
    
    class AAA{ //父类
        {
            System.out.println("AAA的普通代码块");
        }
    
        public AAA() {
            System.out.println("AAA() 构造器被调用");
        }
    }
    
    class BBB extends AAA{
        {
            System.out.println("BBB的普通代码块");
        }
    
        public BBB() {
            System.out.println("BBB()构造器被调用");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    运行结果

    在这里插入图片描述

    【创建一个子类对象时(继承关系),他们的静态代码块、静态属性初始化、普通代码块、普通属性初始化、构造方法的调用顺序】

    1. 父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
    2. 子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
    3. 父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
    4. 父类的构造方法
    5. 子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
    6. 子类的构造方法

    静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。

    举个栗子

    package com.dingjiaxiong.codeblock_;
    
    /**
     * ClassName: CodeBlockDetail04
     * date: 2022/9/3 17:28
     *
     * @author DingJiaxiong
     */
    
    public class CodeBlockDetail04 {
        public static void main(String[] args) {
            new B02();
    
            new C02();
        }
    }
    
    class A02{ //父类
        private static int n1 = getVal01(); //静态属性初始化
    
        static {
            System.out.println("A02的一个静态代码块...");
        }
        {
            System.out.println("A02的第一个普通代码块...");
        }
    
        public int n3 = getVal02(); //普通属性初始化
    
        public static int getVal01(){
            System.out.println("getVal01");
            return 10;
        }
    
        public int getVal02(){
            System.out.println("getVal02");
            return 10;
        }
    
        public A02(){
            System.out.println("A02的构造器");
        }
    }
    
    class C02{
        private int n1 = 100;
        private static int n2 = 200;
    
        private void m1(){
    
        }
    
        private static void m2(){
    
        }
    
        static {
            //静态代码块,只能调用静态成员
            System.out.println(n2);
            m2();
        }
    
        {
            //普通代码块,可以使用任意成员
            System.out.println(n1);
            System.out.println(n2);
            m1();
            m2();
        }
    }
    
    class B02 extends A02{
        private static int n3 = getVal03();
    
    
    
        static {
            System.out.println("B02的一个静态代码块...");
        }
    
        public int n5 = getVal04();
    
        {
            System.out.println("B02的一个普通代码块...");
        }
    
        private static int getVal03() {
            System.out.println("getVal03");
            return 10;
        }
    
        public int getVal04(){
            System.out.println("getVal04");
            return 10;
        }
    
        public B02() {
            System.out.println("B02的构造器");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    运行结果

    在这里插入图片描述

  • 相关阅读:
    CANape XCP on Eth工程创建
    【计算机视觉】SimSiam 讲解
    SpringBoot学习
    华为云HECS服务器下docker可视化(portainer)
    15、设计模式之迭代器模式(Iterator)
    【11.2】【VP】Codeforces Round #728 (Div. 2)
    如何将不同类别信息发送到kafka的不同通道中
    springboot防止表单重复提交
    Go/Golang语言学习实践[回顾]教程13--详解Go语言的词法解析单元
    微信小程序二维码
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/126900747