JAVA 代码块介绍

一、基本介绍

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

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

注意: 1)修饰符 可选,要写的话,也只能写 static。

2)代码块分为两类,使用static 修饰的叫静态代码块,没有static修饰的,叫普通代码块。

3)逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)。

4);号可以写上,也可以省略。

理解:

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

代码演示:
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;
    // 3 个构造器 -> 重载
    //解读
    //(1) 下面的三个构造器都有相同的语句
    //(2) 这样代码看起来比较冗余
    //(3) 这时我们可以把相同的语句,放入到一个代码块中,即可
    //(4) 这样当我们不管调用哪个构造器,创建对象,都会先调用代码块的内容
    //(5) 代码块调用的顺序优先于构造器
    {
        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) {
        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.细节一

public class CodeBlockDetail01 {
    public static void main(String[] args) {
        //类被加载的情况举例
        // 1. 创建对象实例时(new)
        // AA aa = new AA();
        
        // 2. 创建子类对象实例,父类也会被加载, 而且,父类先被加载,子类后被加载
        // AA aa2 = new AA();
        
        // 3. 使用类的静态成员时(静态属性,静态方法)
        // System.out.println(Cat.n1);
        // static 代码块,是在类加载时,执行的,而且只会执行一次. // DD dd = new DD();
        // DD dd1 = new DD();
        // 普通的代码块,在创建对象实例时,会被隐式的调用。
        // 被创建一次,就会调用一次
        // 如果只是使用类的静态成员时,普通代码块并不会执行
        System.out.println(DD.n1);//8888, 静态模块块一定会执行
    }
}
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 被执行...");//1
    }
}
class AA extends BB {
    //静态代码块
    static {
        System.out.println("AA 的静态代码 1 被执行...");//2
    }
}

2.细节二

public class CodeBlockDetail02 {
    public static void main(String[] args) {
        A a = new A();
        //执行顺序
        // (1) A 静态代码块 01 
        // (2) getN1 被调用...
        // (3) A 普通代码块 01
        // (4) getN2 被调用...
        // (5) 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 int getN2() { //普通方法/非静态方法
        System.out.println("getN2 被调用...");
        return 200;
    }
    //无参构造器
    public A() {
        System.out.println("A() 构造器被调用");
    }
}

3.细节三

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

因此是优先于 构造器和普通代码块执行。

class A {
    public A(){//构造器
        //这里有隐藏的执行要求
        //隐藏的 super();//调用普通代码块
        System.out.println("ok"");
   }
}
public class CodeBlockDetail03 {
    public static void main(String[] args) {
        new BBB();
        //(1)AAA 的普通代码块
        //(2)AAA() 构造器被调用
        //(3)BBB 的普通代码块
        //(4)BBB() 构造器被调用
    }
}
​
class AAA { //父类 Object
    {
        System.out.println("AAA 的普通代码块");
    }
​
    public AAA() {
        //(1)super()
        //(2)调用本类的普通代码块
        System.out.println("AAA() 构造器被调用....");
    }
​
}
​
class BBB extends AAA {
    {
        System.out.println("BBB 的普通代码块...");
    }
​
    public BBB() {
        //(1)super()
        //(2)调用本类的普通代码块
        System.out.println("BBB() 构造器被调用....");
    }
}

4.细节四

1)我们看一下创建一个子类时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:

  1. 父类的静态代码块和静态属性(优先级一样,按定义顺序执行)

  2. 子类的静态代码块和静态属性(优先级一样,按定义顺序执行)

  3. 父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

  4. 父类的构造方法

  5. 子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

  6. 子类的构造方法 // 面试题

  7. 静态方法与普通方法只有在调用时才执行,与顺序无关

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

public class CodeBlockDetail04 {
    public static void main(String[] args) {
        //说明
        //(1) 进行类的加载
        //1.1 先加载 父类 A02 1.2 再加载 B02
        //(2) 创建对象
        //2.1 从子类的构造器开始
        new B02();//对象
        new C02();
    }
}
​
class A02 { //父类
    private static int n1 = getVal01();
​
    static {
        System.out.println("A02 的一个静态代码块..");//(2)
    }
​
    {
        System.out.println("A02 的第一个普通代码块..");//(5)
    }
​
    public int n3 = getVal02();//普通属性的初始化
​
    public static int getVal01() {
        System.out.println("getVal01");//(1)
        return 10;
    }
​
    public int getVal02() {
        System.out.println("getVal02");//(6)
        return 10;
    }
​
    public A02() {//构造器
        //隐藏
        //super()
        //普通代码和普通属性的初始化...... System.out.println("A02 的构造器");//(7)
    }
}
​
class C02 {
    private int n1 = 100;
    private static int n2 = 200;
​
    private void m1() {
    }
​
    private static void m2() {
    }
​
    static {
        //静态代码块,只能调用静态成员
        //System.out.println(n1);错误
        System.out.println(n2);//ok
        //m1();//错误
        m2();
    }
​
    {
        //普通代码块,可以使用任意成员
        System.out.println(n1);
        System.out.println(n2);//ok
        m1();
        m2();
    }
}
​
class B02 extends A02 { //
    private static int n3 = getVal03();
​
    static {
        System.out.println("B02 的一个静态代码块..");//(4)
    }
​
    public int n5 = getVal04();
​
    {
        System.out.println("B02 的第一个普通代码块..");//(9)
    }
​
        System.out.println("getVal03");//(3)
        return 10;
}
​
    public int getVal04() {
        System.out.println("getVal04");//(8)
        return 10;
    }
    // public B02() {//构造器
    //隐藏了
    //super()
    //普通代码块和普通属性的初始化... System.out.println("B02 的构造器");//(10)
    // TODO Auto-generated constructor stub
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/785965.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java面试八股之MySQL支持哪些数据类型

MySQL支持哪些数据类型 MySQL支持多种数据类型,这些类型可以大致分为三大类:数值类型、日期/时间类型和字符串类型。下面是一些常见的数据类型及其用途: 数值类型 整数类型: TINYINT:通常占用1字节。 SMALLINT&am…

注册商标为什么要先查询

注册商标为什么要先查询 在知识产权日益受到重视的今天,商标的注册成为了许多企业和个人保护其品牌价值和市场地位的重要手段。然而,商标注册并非一蹴而就的过程,其中一个关键的步骤就是商标查询,也就是我们通常所说的“商标检索…

STM32CubeMX如何配置生成项目以及安装包

目录 一、STM32CubeMX介绍 二、用STM32CubeMX生成项目 1.创建项目 2.定义引脚 3.配置时钟 4.保存项目 5.生成项目 6.打开项目 一、STM32CubeMX介绍 STM32CubeMX是STM32Cube工具家族中的一员,专门为STM32微控制器的开发提供便利。它是一款图形化工具&#xf…

新加坡工作和生活指北:租房篇

本文首发于公众号 Keegan小钢 前段时间已经分享了工作篇,现在接着聊聊生活篇。因为生活这块涉及到多个方面,内容比较多,所以我再细分了一下,本篇先聊聊租房。 先来看看新加坡的地区分布图,如下: 上图将新加…

【C语言】指针(3):探索-不同类型指针变量

目录 一、字符指针变量 二、数组指针变量 三、二维数组传参的本质 四、函数指针变量 4.1 函数指针变量 4.2 函数指针变量的使用 4.3 函数指针变量的拓展 五、函数指针数组 六、转移表的应用 通过深入理解指针(1)和深入理解指针(2&am…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第十二章 Linux 权限管理

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

Python 插入、替换、提取、或删除Excel中的图片

Excel是主要用于处理表格和数据的工具,我们也能在其中插入、编辑或管理图片,为工作表增添视觉效果,提升报告的吸引力。本文将详细介绍如何使用Python操作Excel中的图片,包含以下4个基础示例: 文章目录 Python 在Excel…

Autogen基本使用介绍

文章目录 一,Build1,Skill2,Models3,agents4,workflow 二,Playground 本文唯一目的就是介绍一下Autogen Studio的基本的使用。 打开这个网页以后,看到它有2个菜单,分别是: BuildPla…

07-7.3.2 平衡二叉树(AVL)

👋 Hi, I’m Beast Cheng 👀 I’m interested in photography, hiking, landscape… 🌱 I’m currently learning python, javascript, kotlin… 📫 How to reach me --> 458290771qq.com 喜欢《数据结构》部分笔记的小伙伴可以…

使用 Qt 和 ECharts 进行数据可视化

文章目录 示例图表预览折线图散点图柱状图使用 Qt 和 ECharts 进行数据可视化一、准备工作1. 安装 Qt2. 准备 ECharts二、在 Qt 中使用 ECharts1. 创建 Qt 项目2. 配置项目文件3. 在 UI 中添加 WebEngineView4. 加载 ECharts三、创建折线图、散点图和柱状图1. 折线图2. 散点图3…

工作流之战: Flowable vs. Camunda vs. Activiti

欢迎来到我的博客,代码的世界里,每一行都是一个故事 🎏:你只管努力,剩下的交给时间 🏠 :小破站 工作流之战: Flowable vs. Camunda vs. Activiti 前言功能特性对比架构设计分析性能比较使用场景…

zookeeper加入开机启动项

Windows的任务计划程序(Task Scheduler)是一个强大的工具,允许你安排程序在特定时间自动运行,包括开机时。 打开任务计划程序: 按下Win R键,打开“运行”对话框。输入taskschd.msc并回车,打开…

js ES6 part1

听了介绍感觉就是把js在oop的使用 作用域 作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问, 作用域分为: 局部作用域、 全局作用域 1. 函数作用域: 在函数内部声明的…

Docker定时清理

一、循环调度执行 1、检查cron状态 systemctl status crond 2、创建要执行的shell脚本 vim /home/cleanup_docker.sh #! /bin/bash # 清理临时文件 echo $(date "%H:%M:%S") "执行docker清理命令..." docker system prune -af-a 清理包括未使用的镜像 …

Vue3动态路由(响应式带参数的路由)变更页面不刷新的问题

背景 先说说问题,问题来源是因为我的开源项目Maple-Boot项目的网站前端,因为项目主打的内容发布展示,所以其中的内容列表页会根据不同的菜单进行渲染不同的路由。 这里路由path使用的是/blog/:menu?,通过menu的参数来渲染对应的…

很多人对AI Agent的理解太片面

现在 AI 智能体(AI Agent)的概念很火,似乎 Agent 是用 AI 解决问题的银弹,有了 Agent 就可以解决很多问题。但也有很多人有不同意见,认为 Agent 不过是噱头,并没有看到靠谱的应用场景。 一个被提及很多的是…

openlayers更改点坐标

我现在的需求是无人机点位根据ws传输的经纬度改变位置,在网上查了很多资料,终于是做出来了,如果有问题请指出。 效果图,无人机可以来回移动 这里是核心代码 // 添加飞机点位图层let vectorLayerpointfunction DronepointLayer()…

Windows远程桌面的奇技淫巧

前言 Windows远程桌面简介 远程桌面协议(RDP)是一个多通道(multi-channel)的协议,让使用者连上提供微软终端机服务的计算机(称为服务端或远程计算机) 远程桌面的前置条件 在获取权限后,针对3389进行展开,先查询3389端口是否开启 netstat…

PHP工单预约表单系统小程序源码

🔧【高效办公新利器】工单预约表单系统大揭秘 💼【一键提交,工单管理新高度】 你还在为繁琐的工单提交流程头疼吗?工单预约表单系统,让你的工单管理步入高效时代!只需简单几步,填写必要信息&a…

记一次线上流量突增问题排查

一.问题 接流量告警出现获取 xx 信息接口调用次数同比往年大促活动猛涨.扩大至 10 倍之多.心里顿时咯噔一下.最近各种严打,顶风作案.某不是摸到电门了.一下子要把自己带走.从此走向求职之路.一时间脑子哇哇的思绪万千. 202x.5.20 大促开门红的调用.这个是往年活动的时候的调用…