static关键字和final关键字
在java的关键字中,static关键字和final关键字是两个必须掌握的关键字。static关键字和final关键字用法多样,且在一定环境下使用,可以提高程序的运行性能,优化程序的结构。下面将依次介绍static关键字和final关键字。注意,某些场景下,staic关键字和final关键字可以联合使用,这里也记录下。
static 关键字
static 关键字可以修饰多种成员,如使用static关键字修饰变量,以表示类变量;使用static关键字修饰方法,以表示类方法;使用static关键字代码块,以表示静态块;使用static关键字修饰内部类,以表示静态内部类;使用static关键字修饰包,以表示静态导包。
static 修饰字段
static关键字可以用来修饰字段,这里的字段仅包括成员变量,被修饰的成员变量也称静态变量。静态变量可以用于存储所有对象的公共属性。如:员工公司名称,学生所在的大学名称。在Java中,静态变量保存在方法区,可以被所有线程共享。静态变量通过较少相同数据的存储来达到节省内存的效果。静态变量的定义很简单,就是使用static关键字修饰成员变量。示例如下:
public class MyClass {public static String staticVariable; // 这是一个静态变量
}
static 修饰方法
static关键字可以用来修饰成员方法,被修饰的成员方法也称类方法。注意,静态方法属于类,不属于类的对象;可以直接调用静态方法,而无需创建类的实例;静态方法可以访问静态变量,并可以更改静态变量的值。静态方法通常用于执行与类本身相关的操作,而不是与特定实例相关的操作。静态方法的定义很简单,就是使用static关键字修饰成员方法。示例如下:
public class MyClass {public static String staticVariable; // 这是一个静态变量public static void staticMethod() {System.out.println("This is a static method.");staticVariable = "foo"; // 在静态方法中更改静态变量的值}
}
静态方法使用上有两个主要限制。它们分别是:(1) 静态方法不能直接使用非静态数据成员或调用非静态方法;(2) this和super两个关键字不能在静态上下文中使用。简言之,静态方法中不能使用对象或对象方法。
最经典的静态方法就是入口类的main方法:
public class Main {public static void main(String[] args) {System.out.println("Hello world.");}
}
这里简单介绍下,为什么Java的main方法是静态的。Java的main方法之所以是静态的,是因为它充当了程序的入口点。当运行一个Java程序时,JVM会首先寻找具有静态main方法的类,然后调用该类的main方法。main方法的关键特性有:
(1) main方法是一个静态方法。这意味着它不需要创建类的实例就可以被调用,减少不必要的对象创建。
(2) main方法具有特定的签名:它接收一个字符串数组作为参数。这是因为JVM通过命令行参数将数据传递给程序。
(3) 当运行Java程序时,JVM会自动调用具有静态main方法的类的main方法。
static 修饰代码块
static关键字可以用来修饰代码块,别修饰的代码块也称静态块。静态块主要用于初始化类,为类的静态变量赋初始值,提升程序性能。静态块有以下特点:
(1) 静态块类似于一个方法,但它不可以存在于任何方法体中。
(2) 静态块可以置于类中的任何地方,类中可以有多个静态初始化块。
(3) Java 虚拟机在加载类时执行静态代码块,很多时候会将一些只需要进行一次的初始化操作都放在静态块中进行。
(4) 如果类中包含多个静态代码块,则 Java 虚拟机将按它们在类中出现的顺序依次执行它们,每个静态代码块只会被执行一次。
静态块的定义很简单,就是使用"static + {}"的方式定义。示例如下:
public class MyClass {public static String staticVariable; // 这是一个静态变量static {staticVariable = "foo-1";System.out.println(staticVariable);}static {staticVariable = "foo-2";System.out.println(staticVariable);}
}
在上面的示例代码中,两个静态块按照在类中出现的顺序依次执行,所以staticVariable先被赋值为"foo-1",然后被赋值为"foo-2"。
static 修饰内部类
static关键字可以用来修饰内部类,被修饰的内部类称为静态内部类。静态内部类也称为嵌套类(这里特指Java语言)。静态内部类是一种特殊的内部类,当外部类在加载时,并不会立即加载其静态内部类,而是在第一次调用静态内部时,才会初始化静态内部类。所以,静态内部类可以实现延迟加载的效果。静态内部类的定义很简单,就是使用static关键字修饰内部类。示例如下:
public class OuterClass {private String privateField;private static String privateStaticField;private void visit() {// 外部类可以直接访问静态内部类的静态成员System.out.println(StaticInnerClass.privateStaticField);// 外部类可以实例化静态内部类,并访问该实例的私有成员StaticInnerClass staticInnerClass = new StaticInnerClass();System.out.println(StaticInnerClass.privateStaticField);}static class StaticInnerClass {private String privateField;private static String privateStaticField;public static void visit() {// 静态内部类方法中,可以直接使用外部类的静态私有成员System.out.println(OuterClass.privateStaticField);// 静态内部类方法中,可以实例化外部类,并访问外部类实例的私有成员OuterClass outerClass = new OuterClass();System.out.println(outerClass.privateField);}}
}
静态内部类的经典使用场景是基于静态内部类实现单例模式,示例代码如下:
public class Singleton {private Singleton() {}// 静态方法public static Singleton getInstance() {return SingletonHolder.INSTANCE;}// 静态内部类private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}
}
使用静态内部类实现单例模式,不仅可以实现延迟加载,还能确保线程安全,也能保证单例的唯一性。更多静态内部类的说明可以参考Java内部类一文。
static 修饰包
static关键字可以用来修饰包,被修饰的包称为静态导包。JDK 在 1.5 版本支持静态导包。静态导包简化了静态变量或静态方法的使用。采用static导入包后,在不与当前类的方法名冲突的情况下,无需使用“类名.方法名”的方法去调用类方法,而是可以直接可以采用"方法名"去调用类方法,就好像是调用该类自己的方法一样。静态导包的实现很简单,就是在导入外部类时,额外添加static关键字。示例代码如下:
package xxx;// (1) 定义待引用的类并定义静态方法
public class CustomClass {public static void customStaticMethod(Object o){System.out.println(o);}
}
// (2) 在import包的同时,使用static关键字,并在引入类的最后加上".*"
import static xxx.CustomClass.*;public class Main {public static void main( String[] args ) {customStaticMethod("Hello World!");}
}
需要说明的是,虽然静态导包使代码更简洁,但可能会导致无法区分类方法和成员方法,从而导致代码的可读性和可维护性降低。在日常的编码活动中,并不推荐静态导包的写法。
final关键字
final 关键字可以修饰多种成员,如使用static关键字修饰数据,具体包括成员变量、局部变量、方法参数等;使用final关键字修饰方法,以防止方法被覆盖;使用final关键字修饰类,以防止该类被继承。
final 修饰数据
当在一个数据(成员变量、局部变量、方法参数)前使用final关键字时,这意味着这个数据的值是固定的,不能被改变,也即一个永不改变的编译时常量。注意final修饰的数据允许不初始化,也即"空白final"。空白final是指被声明为final但又未给定初值的字段。编译器需确保空白final在使用前必须被初始化。空白final修饰的变量一旦在运行时被初始化,就不会再改变。
注意,static关键字可以和final关键字联合使用修饰变量,表示不可变的类常量。
final修饰数据的方式很简单,就是在待修饰的数据前补充final关键字,示例如下:
public class MyClass {// static+final修饰变量,表示不可变的类常量private static final String FLAG = "red";// 空白finalprivate final String code;// final修饰的成员变量private final String name = "jack";public FinalDemo() {// 空白final修饰变量的初始化this.code = "foo";}public void testFinalParam(final String param) {// param = "new value"; // Cannot assign a value to final variable 'param'System.out.println(param);final String localVariable = "test"; //final修饰的局部变量// localVariable = "new value"; // Cannot assign a value to final variable 'localVariable'System.out.println(localVariable);}
}
说明,final参数的语义是不可在方法体中修改参数。对于基本类型,表示该基本类型不可被重新赋值;对于引用类型,表示不能更改参数引用所指向的对象。
final 修饰方法
final关键字可以用来修饰成员方法,这意味着这个方法不能被重写或重载。final关键字用于表示方法已锁定,其子类无法修改它的含义。使用final关键字修饰的方法可以在编译期转化为内嵌方法,从而提供执行效率。但是因为这种优化效率并不高,所以不再作为特性使用。final关键修饰方法很简单,就是使用final关键字修饰成员方法。示例如下:
public class Main {public final void test1() {System.out.println("test1");}
}
注意,所有private方法都隐式指定为final。 需要说明的是,final方法并没有控制方法的访问权限,只是保证该方法不可被子类覆盖。如可以使用public权限控制final方法的访问权限。示例如下:
public class Main {public final void test1(){System.out.println("test1");}protected final void test2(){System.out.println("test2");}private final void test3(){System.out.println("test3");}
}
final 修饰类
final关键字可以用来修饰类,这意味着这个方法不能被继承。需要说明的是,因为final修饰的类不可继承,所以其方法均为final。final关键修饰类很简单,就是使用final关键字修饰类。示例如下:
public final class Main {public final void test1(){System.out.println("test1");}
}
与final关键字修饰成员方法类似,final修饰类时,并不能控制类的访问权限,只是保证该类不可被继承。常见的String类就是一个使用final修饰的类,对应源码如下:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {@Stableprivate final byte[] value;// ...
}
static和final联合使用
static和final可以联合使用,且目前为止只能用来修饰字段和方法。其实,两者联合使用,并没有特别处理,只是各自表示各自的含义,并没有1+1>2的效果。
static 关键字表示该变量或方法是属于类的,而不是属于类的任何一个实例的。因此,静态变量或方法可以在没有创建类的实例的情况下进行访问。
而final 关键字表示该变量或方法是一个常量或不可变的方法,其值不能被改变或方法不可覆盖。
static 关键字和 final 关键字结合使用,就表示以创建不可变的常量或不可变的静态方法。需要注意的是,当使用static关键字和final关键字修饰方法时,因为静态方法不属于对象,所以不存在被覆盖的情况,所以实际的应用中,使用static关键字修饰的方式可以不用final关键字修饰。示例代码如下:
public class MyClass {public static final float MY_CONSTANT = 3.14f;public static final void test() {System.out.println("test");}
}
在上面的代码中,使用 static 关键字和 final 关键字定义了一个不可变的静态常量 MY_CONSTANT,其值为 3.14。由于 MY_CONSTANT 是静态的,因此可以在没有创建 MyClass 类的实例的情况下访问它;由于它是常量的,因此它的值不能被改变。
使用 static 关键字和 final 关键字定义的test方法,由于static修饰的方法已表示静态方法,所以不存在被覆盖的情况,所以可以省略final关键字。
参考
《Java编程思想》(第四版) Bruce Eckel [译]陈昊鹏
https://www.yiibai.com/java/static-keyword-in-java.html Java static关键字
https://www.cnblogs.com/dotgua/p/6354151.html java static关键字的四种用法
https://www.changchenghao.cn/n/562466.html static变量放JVM哪个区域(static关键字基本概念和应用)
相关文章:
static关键字和final关键字
在java的关键字中,static关键字和final关键字是两个必须掌握的关键字。static关键字和final关键字用法多样,且在一定环境下使用,可以提高程序的运行性能,优化程序的结构。下面将依次介绍static关键字和final关键字。注意ÿ…...
使用Postman如何在接口测试前将请求的参数进行自定义处理
1、前言 当我们使用 Postman 进行接口测试时,对于简单的不需要处理的接口,直接请求即可,但是对于需要处理的接口,如需要转码、替换值等,则就麻烦一些,一般我们都是先手动把修改好的值拷贝到请求里再进行请…...
QT第二天
1.优化登陆界面,当点击登录按钮后,在该按钮对应的槽函数中,判断账户和密码框内的数据是否为admin和123456,如果账户密码匹配成功,则提示登陆成功并关闭登录界面,如果账户密码匹配失败,则提示登录…...
鸿蒙应用程序入口UIAbility详解
一、UIAbility概述 UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。每一个UIAbility实例,都对应于一个最近任务列表中的任务。一个应用可以有一个UIAbility&am…...
扫地僧站群·静态养站王:自动万站智能LOGO功能说明
扫地僧站群静态养站王:自动万站智能LOGO功能说明,无需配置,自动根据网站状态生成对应LOGO,高质量LOGO万站不重样.说明:模板调用智能LOGO方式:{当前域名}/logo.png 自动识别HTTP/HTTPS 只需在模板需要展示LOGO的地方放上如上标签即可。以下为L…...
【Day-32慢就是快】代码随想录-二叉树-合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接…...
接口测试系列 —— 什么是接口测试?
接口测试系列 为什么要做这个事情? 对自己过往在接口测试上的经验,写一个小结的系列文章,是一个系统性的思考和知识构建。发布的同时,也是希望获得更多感兴趣的同学的意见和反馈,可以把这个部分做的更好。 接口测试概…...
qt作业day2
//widget.cpp#include "widget.h" #include "ui_widget.h"void Widget::usr_login() {if("admin" this->edit_acc->text()){if("123456" this->edit_psd->text()){speech->say("登录成功");emit jump_sig1…...
JWT一篇通
JWT 是什么? JWT(JSON Web Token)是一种开放的标准,标准的编号是RFC7591。用于在不同实体之间安全地传输信息。它是基于 JSON 编码的令牌。 JWT 的组成 JWT由三个部分组成:头部(Header)、载荷…...
【2023-09-01】vue中自定义按钮设置disabled属性后,异常触发click事件
vue中自定义按钮设置disabled属性后,异常触发click事件 项目中自定义按钮,使用a标签实现。设置disabled属性后,点击可以触发click事件。 由于各种原因,项目中并未使用成熟的第三方组件库,例如element-ui,a…...
nginx报错file not found解决
文章目录 一、nginx配置文件修改1.1 配置文件位置1.2 php fastcgi配置1.3 测试 二、nginxphp运行原理三、外网访问内网设置 采用nginxphp作为webserver的架构模式,在现如今运用相当广泛。然而第一步需要实现的是如何让nginx正确的调用php。由于nginx调用php并不是如…...
【力扣】96. 不同的二叉搜索树 <动态规划>
【力扣】96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n 3 输出:5 示例 2: 输入&am…...
Win11搭建 Elasticsearch 7 集群(一)
一: ES与JDK版本匹配一览表 elasticsearch从7.0开始默认安装了java运行环境,以便在没有安装java运行环境的机器上运行。如果配置了环境变量JAVA_HOME,则elasticsearh启动时会使用JAVA_HOME作为java路径,否则使用elasticsearch根目…...
哭了,python自动化办公,终于支持 Mac下载了
想了解更多精彩内容,快来关注程序员晚枫 大家好,这里是程序员晚枫,小红薯/小破站也叫这个名。 在我的主页发布的免费课程:给小白的《50讲Python自动化办公》,一直在更新中,昨晚12点多,有朋友在…...
【已更新建模代码】2023数学建模国赛B题matlab代码--多波束测线问题
一、 问题重述 1.1问题背景 海洋测深是测定水体深度与海底地形的重要任务,有两种主要技术:单波束测 深与多波束测深。单波束适用于简单任务,但多波束可提供更精确的地形数据。多 波束系统的关键在于覆盖宽度与重叠率的设计,以确保…...
GMSL技术让汽车数据传输更为高效(转)
目前,大部分车企都在其旗舰车型上配备了达到Level 2水平的自动驾驶技术,也就是高级自动驾驶辅助 ADAS系统。ADAS系统硬件主要由以下几部分组成,包括传感器、串行器、解串器、ADAS处理器等。 除了ADAS系统,包括传感器融合、音视频影…...
ARM+Codesys标准通用型控制器
整机工业级设计,通讯外设经过隔离保护 电源宽电压设计(9~36V DC ) 丰富的通讯接口,满足多种场合控制和通讯需求 四核工业级处理器,高性能,低功耗,高可靠性 机身无风扇设计,外壳小巧 搭载内核 100% 自主…...
YOLOV8从零搭建一套目标检测系统(修改model结构必看)附一份工业缺陷检测数据集
目录 1.YOLOV8介绍 2.YOLOV8安装 2.1环境配置 3.数据集准备 1.YOLOV8介绍 Yolov8结构图: YoloV8相对于YoloV5的改进点: Replace the C3 module with the C2f module. Replace the first 6x6 Conv with 3x3 Conv in the Backbone. Delete two Convs …...
Maven 的其它插件
文章目录 Maven 的其它插件dockerfile 插件Apache Maven Checkstyle Pluginp3c-pmd Maven 的其它插件 dockerfile 插件 dockerfile-maven-plugin 是 spotify 公司新提供的、用以替代 docker-maven-plugin 的插件,它同样是用于在 maven 中将当前项目打成一个 docke…...
系列十三、Java操作RocketMQ之带Key的消息
一、概述 RocketMQ中的消息,默认会有一个messageId当做消息的唯一标识,我们也可以给消息携带一个key,用作唯一标识或者业务标识,包括在控制面板(Dashboard,RocketMQ的一个可视化面板)中也可以使…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
