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关键字基本概念和应用)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于scipy库的入门教程

本教程将介绍如何使用Scipy库进行科学计算和数据分析。Scipy是一个基于NumPy的开源Python库&#xff0c;提供了很多高级的数学函数和科学计算工具。 安装Scipy库 在开始教程之前&#xff0c;首先需要安装Scipy库。可以使用以下命令进行安装&#xff1a; pip install scipy导入…

go的gin框架实现接受多个图片和单个视频并保存到本地服务器的接口

首先是接受多个图片的接口&#xff0c;就是接受多个文件 收到post请求后首先创建一个文件夹&#xff0c;这里利用uuid创建出唯一标识字符串作为文件夹名称&#xff0c;解析表单中的一串文件循环保存到本地服务器 package mainimport ("github.com/gin-gonic/gin"&q…

iveiw 时间验证

最近遇到在使用iview框架时&#xff0c;在商家后端管理系统中&#xff0c;在合同发布时会使用到form表单组件&#xff0c;当然日期也通常出现在搜索 框表单中&#xff0c;但是有时候会出现日期组件校验错误的情况 首先&#xff0c;iview采用的是async-validator的校验规则&…

SwiftUI简单基础知识学习

以下是一个大致的学习计划&#xff0c;将SwiftUI的知识分成12个主题&#xff1a; SwiftUI 简介和基础语法视图和布局状态和数据流按钮和用户输入列表和数据展示导航和页面传递动画和过渡效果手势和交互绘制和绘图多平台适配网络和数据请求实际项目实践和高级主题 每个主题可以…

go开发之个微机器人的二次开发

请求URL&#xff1a; http://域名/addRoomMemberFriend 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是String登录实例标识chatRoom…

如何把Android Framework学彻底?一条龙学习

Framework通俗易懂 平时学习 Android 开发的第一步就是去学习各种各样的 API&#xff0c;如 Activity&#xff0c;Service&#xff0c;Notification 等。其实这些都是 Framework 提供给我们的。Framework 层为开发应用程序提供了非常多的API&#xff0c;我们通过调用这些 API …

系统数据大屏开发适配方案。

原理&#xff1a;通过css样式transform的属性scale实现展示盒子的缩放实现适配。 直接上干货&#xff1a; 监听屏幕的缩放&#xff1a; mounted() {this.$nextTick(() > {this.changeScale()})window.addEventListener(resize, this.changeScale); //监听屏幕的缩放},be…

约瑟夫环实现

约瑟夫环 约瑟夫环小游戏&#xff1a;把小朋友按照编号1&#xff0c;2&#xff0c;3&#xff0c;…&#xff0c;n围成一圈&#xff0c;指定编号为k的小朋友从1开始报数&#xff0c;数到m的小朋友出队。接着他的下一位小朋友再次从1报数&#xff0c;以此类推&#xff0c;直到所有…

计算机毕业设计 基于SSM的问卷调查管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

uniApp常见面试题-附详细答案

uniApp中如何进行页面跳转&#xff1f; 答案&#xff1a;可以使用uni.navigateTo、uni.redirectTo和uni.reLaunch等方法进行页面跳转。其中&#xff0c;uni.navigateTo可以实现页面的普通跳转&#xff0c;uni.redirectTo可以实现页面的重定向跳转&#xff0c;uni.reLaunch可以实…

qt day 5

实现局域网的网络聊天室功能 1>服务器代码 --------------------------------------------------------------- widget.h --------------------------------------------------------------- #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMes…

golang入门笔记——nginx

文章目录 Nginx介绍Nginx的安装Nginx文件Nginx反向代理负载均衡nginx动静分离URLRewrite防盗链nginx高可用配置安全性Nginx限流Nginx缓存集成Lua脚本OpenRestry Nginx介绍 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;特点是占用内存少&#xff0c;并发能力强&#x…

52、基于函数式方式开发 Spring WebFlux 应用

★ Spring WebFlux的两种开发方式 1. 采用类似于Spring MVC的注解的方式来开发。此时开发时感觉Spring MVC差异不大&#xff0c;但底层依然是反应式API。2. 使用函数式编程来开发★ 使用函数式方式开发Web Flux 使用函数式开发WebFlux时需要开发两个组件&#xff1a; ▲ Han…

一.使用qt creator 设计显示GUI

一.安装qt creator 二.创建项目 文件-》新建项目 三.使用设计 可以直接使用鼠标拖拽 四.转换为py文件 # from123.py 为导出 py文件的文件名 form.ui 为 qt creator创造的 ui 文件 pyuic5 -o x:\xxx\from123.py form.ui五.显示GUI from PyQt5.QtWidgets import * fr…

Android高通 8.1 老化apk打开摄像头花屏问题

1、最近由于公司VR 3D系统要做双Camera老化测试apk&#xff0c;同时老化4小时需要轮询切换二个摄像头&#xff0c;保证后面camera标定精度数据更准确。 2、一开始我尝试用之前方案移植过去然后同时打开双摄像头 突然发现花屏 如下图所示 3、于是一第一时间想到是不是分辨率不兼…

在UI设计中用什么样的字体?优漫动游

在windos下支持的字体 在UI设计中用什么样的字体&#xff1f; 宋体&#xff08;simsun&#xff09;&#xff1a;在win下大部分的浏览器是默认的&#xff0c;适合小字号&#xff0c;不太适合大字号。 微软雅黑&#xff1a;是目前win浏览器中最值得使用的。 Arial&#…

算法通关村——滑动窗口高频问题

1. 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 1.1 滑动窗口 找到最长字串需要找到字串的首尾位置…

c++保留n位小数输出(百分数形式,保留n位有效数字,设置宽度)

在C中&#xff0c;你可以使用 头文件中的一些函数和控制符来控制输出的小数位数、百分数形式以及设置宽度。下面我将详细讲解如何实现这些功能。 控制小数位数 若要在输出中控制小数位数&#xff0c;你可以使用 std::setprecision 函数。这个函数接受一个整数参数&#xff0c…

多组背包恰好装满方案数

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 现在有一个大小n*1的收纳盒&#xff0c;我们手里有无数个大小为1*1和2*1的小方块&#xff0c;我们需要用这些方块填满收纳盒&#xff0c;请问我们有多少种不同的方法填满这个收纳盒 分析&…

关于 Unity 连接 MuMu 模拟器上的 Unity Remote 5 的方法

在使用 Unity 开发 Android 的过程中&#xff0c;可以通过使用 Unity Remote 这个 app 来和真机连接&#xff0c;进而在真实环境下进行测试性能等工作&#xff0c;而本次则是由于其他问题引出的一个小坑&#xff0c;记录以备后续查询。 这次是由于在自学过程中遇到的一个工程&…