IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java 代码块详解 -> 正文阅读

[Java知识库]Java 代码块详解

Java 代码块详解

基本介绍

代码块又称 初始化块, 是类的一部分,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过 {} 封装起来。
但是代码块没有方法名,没有返回,没有参数, 只有方法体,而且不用通过对象或类显示调用,而是加载类的时候,或创建对象的时候隐式调用。

基本语法

在这里插入图片描述

  1. 修饰符可选,并且修饰符只能为 static
  2. 代码块分为两类,用 static 修饰的为静态代码块,没有 static 修饰的为普通代码块
  3. 代码块中可以写任何语句(输入,输出,方法调用,循环,判断等等)。
  4. ; 可以省略。

代码块示例

student类

public class Student {
    private int id;
    private String name;
    private int age;

    {
        System.out.println("代码块被执行~~");
    }

    public Student(int id, String name, int age) {
        System.out.println("构造器被调用~~~");
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

BlockCodeTest类

public class BlockCodeTest {
//    代码块调用的顺序优先于构造器
    public static void main(String[] args) {
        Student s = new Student(1, "王昭君", 18);
    }
}

运行结果:
在这里插入图片描述
通过运行结果我们发现,代码块调用的顺序优先于构造器的,所以,代码块相当于另外一种形式的构造器,可以作为构造器的补充机制,做初始化的操作。

代码块使用细节

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

🚀类加载时机 非常重要

1.创建实例对象时(new)
2.创建子类对象实例时,父类也会被加载
3.使用类的静态成员时(静态属性、静态方法)

代码示例1 【创建实例对象时(new)】

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

class A {
    static {
        System.out.println("静态代码块被执行~~~");
    }
}

运行结果
在这里插入图片描述

代码示例2 【创建子类对象实例时,父类也会被加载】

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

class A {
    static {
        System.out.println("A类静态代码块执行~~~");
    }
}

class B extends A {
    static {
        System.out.println("B类静态代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述

在实例化B类的对象时,其父类A类也被加载,并且父类加载先于子类。

代码示例3 【使用类的静态成员时】

public class BlockCodeTest {
    public static void main(String[] args) {
        System.out.println(A.num);
    }
}

class A {
    public static int num = 1;
    static {
        System.out.println("A静态代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
调用静态变量,触发类加载,调用了A类的静态代码块。

代码示例4 【静态代码块在类加载时执行,并且只会执行一次】

public class BlockCodeTest {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
    }
}

class A {
    public static int num = 1;
    static {
        System.out.println("A静态代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
static代码块, 是在类加载时执行的, 而且只会执行一次。

2. 普通的代码块,在创建对象实例时,会被隐式调用,被创建一次,就会被调动一次。
可以理解为在用类的构造器实例化对象的时候,构造器中有自动调用普通代码块机制。如果只是使用类的静态成员时,普通代码块并不会执行。
在这里插入图片描述

代码示例1

public class BlockCodeTest {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
        A a3 = new A();
    }
}

class A {
    {
        System.out.println("A普通代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
实例化了3个对象,普通代码块执行了3次。

代码示例2

public class BlockCodeTest {
    public static void main(String[] args) {
        System.out.println(A.num);
    }
}

class A {
    public static int num = 1;
    {
        System.out.println("A普通代码块执行~~~");
    }
    static {
        System.out.println("A静态代码块执行~~~");
    }
}

运行结果:
在这里插入图片描述
使用类的静态成员,普通代码块并不会执行。

🚀小结:

1.static代码块是在类加载时执行的,并且只会执行一次。
2.普通代码块是在创建对象的时候调用的,与类加载无关,创建一次对象,调用一次。

3. 创建一个对象时,在一个类中的调用顺序:
1) 调用静态代码块和静态属性的初始化(静态代码块和静态属性的初始化调用的优先级一样,如果有多个静态代码块和多个静态属性初始化,则按照他们的定义顺序调用)
2) 调用普通代码块和普通属性的初始化(普通代码块和普通属性的初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按照他们定义的顺序调用)
3)最后调用构造方法

代码示例

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

class A {
    //静态属性
    private static int num1 = getVal1();
    //普通属性
    private int num2 = getVal2();

    public A() {
        System.out.println("构造器被执行...");
    }
    //静态代码块
    static {
        System.out.println("A静态代码块儿执行~~");
    }

    //普通代码块
    {
        System.out.println("A普通代码块儿执行");
    }

    public static int getVal1() {
        System.out.println("getVal1执行...");
        return 1;
    }

    public int getVal2() {
        System.out.println("getVal2执行...");
        return 2;
    }
}

运行结果:
在这里插入图片描述
实例化一个A对象,首先产生类加载,完成静态属性的初始化和执行静态代码块(静态代码块和静态属性的初始化调用的优先级一样,因为A类中静态属性的初始化在静态代码块的前面,所以先完成静态属性的初始化),之后执行构造器,因为构造器中有自动调用普通代码块机制和初始化普通属性的机制,所以先完成普通属性的初始化和执行普通代码块(当然这里也没有优先级),最后执行构造器中的代码。

4. 构造器的前面其实隐藏了super() 调用普通代码块

在这里插入图片描述
代码示例

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

class A {
    {
        System.out.println("A类的普通代码块被执行...");
    }

    public A() {
        //super()
        //调用普通代码块
        System.out.println("A类的构造器被调用...");
    }
}

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

    public B() {
        //super()
        //调用本类的代码块
        System.out.println("B类的构造器被调用...");
    }
}

运行结果:
在这里插入图片描述
调用B类构造器的时候,因为构造器中有隐含的super()和调用本类的普通代码块,所以,先执行其父类A类的构造器,其A类同时也有隐含的super()和调用本类的普通代码块,其父类为object,没有相关操作,最后执行结果如上。

5. 有继承关系时,他们的 静态代码块静态属性的初始化 普通属性的初始化 普通代码块 构造方法的调用顺序如下:
父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
父类的普通代码块和普通属性 (优先级一样,按定义顺序执行)
父类的构造方法
子类的普通代码块和普通属性 (优先级一样,按定义顺序执行)
子类的构造方法

代码示例

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

class A {
    private static int num1 = getVal1();
    private int num2 = getVal2();

    {
        System.out.println("A类的普通代码块被执行...");
    }

    static {
        System.out.println("A类的静态代码块被执行...");
    }

    public A() {
        System.out.println("A类构造器被执行");
    }

    public static int getVal1() {
        System.out.println("A类静态属性初始化...");
        return 1;
    }

    public int getVal2() {
        System.out.println("A类普通属性初始化...");
        return 2;
    }
}

class B extends A {
    private static int num1 = getVal11();
    private int num2 = getVal22();

    {
        System.out.println("B类的普通代码块被执行...");
    }

    static {
        System.out.println("B类的静态代码块被执行...");
    }

    public B() {
        System.out.println("B类构造器被执行");
    }

    public static int getVal11() {
        System.out.println("B类静态属性初始化...");
        return 1;
    }

    public int getVal22() {
        System.out.println("B类普通属性初始化...");
        return 2;
    }
}

运行结果:
在这里插入图片描述
6. 静态代码块只能调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:14:49  更:2022-02-28 15:17:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:04:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码