九、static关键字

static关键字

  • 九、static关键字
    • 1. 概述
    • 2. 静态变量
    • 3. 静态块
    • 4. 静态方法
    • 5. 静态内部类
    • 6. 静态导入
    • 7. 静态特性
    • 8. 小结
    • 9. 注意事项

九、static关键字

1. 概述

static是一个关键字,用于定义类、方法、变量和代码块的静态特性。它可以在不同的上下文中使用,并具有不同的含义和功能。

static是静态的意思。 static可以修饰成员变量或者修饰方法。

2. 静态变量

静态变量(类变量):静态变量在类中用static修饰,被称为静态变量或类变量。

它属于类,而不是实例对象。所有的对象共享该变量的值,且可以直接通过类名访问。静态变量在程序运行期间只会被初始化一次。

定义格式

修饰符 static 数据类型 变量名 = 初始值;    
  在类中使用`static`关键字修饰变量,即可定义为静态变量。

例子:

public class Car {static int numberOfCars;String color;public Car(String color) {this.color = color;numberOfCars++;}
}public class Main {public static void main(String[] args) {Car car1 = new Car("red");Car car2 = new Car("blue");System.out.println(Car.numberOfCars); // 输出:2}
}

在上面的例子中,Car类中的numberOfCars变量是静态变量,用于统计创建的Car对象数量。通过在Car的构造方法中对numberOfCars进行自增操作,可以实现每创建一个Car对象就增加一辆车的计数。通过Car.numberOfCars可以直接访问该静态变量,并输出结果为2。

访问方式:

静态变量属于类级别,可以通过类名直接访问,也可以通过类的实例访问。

示例代码如下:

public class MyClass {public static int staticVariable = 10;
}
  • 直接通过类名访问:
int x = MyClass.staticVariable;
  • 通过类的实例访问:
MyClass obj = new MyClass();
int y = obj.staticVariable;

3. 静态块

静态块(静态初始化块): 静态块是一个用static修饰的普通代码块,用于在类加载时执行。

它只会执行一次,并且在类的所有对象之前执行。常用于执行类的静态初始化操作。

定义格式

public class MyClass {static {// 静态块中的代码}
}
使用`static`关键字定义静态块,静态块中的代码在类加载时执行一次			

例子:

public class MathUtils {static double PI;static {PI = 3.14159;System.out.println("静态块执行");}
}public class Main {public static void main(String[] args) {System.out.println(MathUtils.PI); // 输出:3.14159}
}

在上面的例子中,MathUtils类中的静态块用于给静态变量PI赋值,并在执行时输出一条信息。在Main类的main方法中,我们可以直接通过MathUtils.PI访问静态变量PI,输出结果为3.14159。

访问方式:

静态块在类加载时被执行,我们无法在程序中直接访问它。只能通过程序运行过程中访问定义的静态变量、方法或内部类,来触发静态块的执行。

示例代码如下:

public class MyClass {static {System.out.println("静态块被执行");}
}
  • 通过访问静态变量来触发静态块的执行:
int x = MyClass.staticVariable;
  • 通过调用静态方法来触发静态块的执行:

    MyClass.staticMethod();
    
  • 通过访问静态内部类来触发静态块的执行:

    MyClass.StaticInnerClass obj = new MyClass.StaticInnerClass();
    

4. 静态方法

静态方法:静态方法在类中用static修饰,被称为静态方法。

静态方法不依赖于类的实例对象,可以直接通过类名调用。静态方法无法访问非静态的成员变量,只能访问静态的成员变量和调用其他静态方法。

定义格式:

public class MyClass {public static void staticMethod() {// 静态方法中的代码}
}
 使用`static`关键字修饰方法,即可定义为静态方法。

例子:

public class MathUtils {static int add(int a, int b) {return a + b;}
}public class Main {public static void main(String[] args) {int result = MathUtils.add(5, 10);System.out.println(result); // 输出:15}
}

在上面的例子中,MathUtils类中的add方法是一个静态方法,用于计算两个整数的和。在Main类的main方法中,我们直接通过MathUtils.add方法调用该静态方法,并输出结果为15。

访问方式:

静态方法属于类级别,可以直接通过类名调用,也可以通过类的实例调用。

示例如下:

public class MyClass {public static void staticMethod() {// 静态方法中的代码}
}
  • 直接通过类名调用:
MyClass.staticMethod();
  • 通过类的实例调用:
MyClass obj = new MyClass();
obj.staticMethod();

5. 静态内部类

静态内部类:当一个类被声明为静态内部类时,它可以被看作是与外部类独立的一个类,不依赖于外部类的实例。

静态内部类可以直接访问外部类的静态成员,并且不能访问外部类的非静态成员。

定义格式:

public class Outer {static class Inner {// 静态内部类的成员}
}
在外部类中使用`static`关键字定义静态内部类。

例子:

public class Outer {static int outerStaticField;int outerField;static class Inner {void accessOuter() {System.out.println(outerStaticField);}}
}public class Main {public static void main(String[] args) {Outer.Inner inner = new Outer.Inner();inner.accessOuter(); // 输出:0}
}

在上面的例子中,Outer类中定义了一个静态内部类Inner。Inner类中的accessOuter方法可以直接访问Outer类的静态成员outerStaticField,并输出结果为0。

访问方式:

静态内部类被声明为类的静态成员,可以通过外部类名来访问。

示例代码如下:

public class Outer {static class Inner {// 静态内部类的成员}
}
  • 直接通过外部类名访问内部类:
Outer.Inner obj = new Outer.Inner();

6. 静态导入

静态导入:静态导入是指通过使用static import关键字,可以直接导入类的静态成员,而无需使用类名前缀来访问这些静态成员。

定义格式:

import static java.lang.Math.PI;public class MyClass {// 使用静态导入后,可以直接使用静态成员 PI
}
   使用`import static`语句导入类的静态成员,可以直接使用这些静态成员。

例子:

import static java.lang.Math.PI;public class Main {public static void main(String[] args) {System.out.println(PI); // 输出:3.14159}
}

在上面的例子中,通过静态导入可以直接使用Math类的静态成员PI,而无需使用Math.PI这样的类名前缀。

访问方式:

静态导入可以直接使用类中的静态成员,无需使用类名限定符。在导入后,使用静态成员的方式与常规的方式相同。

示例代码如下:

import static java.lang.Math.PI;public class MyClass {double circumference(double r) {return 2 * PI * r;}
}

上例中,静态导入了 java.lang.Math 类中的 PI 常量,可以通过直接使用 PI 来使用这个常量。

7. 静态特性

静态特性具有以下特点:

  • 静态变量是类级别的变量,所有对象共享它们的值。

  • 静态块用于在类加载时执行初始化操作。

  • 静态方法不依赖于对象的实例,可以直接通过类名调用。

  • 静态内部类与外部类独立,可以直接访问外部类的静态成员。

  • 静态导入可以直接导入类的静态成员,无需使用类名前缀。

关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被static修饰的成员是属于类的是放在静态区中,没有static修饰的成员变量和方法则是属于对象的。

8. 小结

  1. static 修饰成员变量或者成员方法时,该变量称为静态变量,该方法称为静态方法。该类的每个对象都共享同一个类的静态变量和静态方法。任何对象都可以更改该静态变量的值或者访问静态方法。但是不推荐这种方式去访问。因为静态变量或者静态方法直接通过类名访问即可,完全没有必要用对象去访问。

  2. 无static修饰的成员变量或者成员方法,称为实例变量,实例方法,实例变量和实例方法必须创建类的对象,然后通过对象来访问。

  3. static修饰的成员属于类,会存储在静态区,是随着类的加载而加载的,且只加载一次,所以只有一份,节省内存。存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。它优先于对象存在,所以,可以被所有对象共享。

  4. 无static修饰的成员,是属于对象,对象有多少个,他们就会出现多少份。所以必须由对象调用。

9. 注意事项

使用静态关键字(static)时需要注意以下几点:

  1. 静态成员属于类而不是实例。它们被所有对象共享,这意味着一处修改会影响到所有相关的对象。静态方法和变量可以通过类名直接访问,而不需要创建类的实例。

  2. 静态变量在类加载时进行初始化,并且只会初始化一次。所有该类的对象共享同一个静态变量的值。

  3. 静态方法无法访问非静态成员(变量和方法),因为非静态成员是与对象相关的。但是非静态方法可以访问静态成员。

  4. 静态方法不能被重写,但可以被重载。这是因为静态方法与类相关而不是对象相关,所以它们的调用是基于声明类型而不是实际类型。

  5. 静态块(static block)可以在类加载时执行一次。它用于初始化静态成员变量,或执行其他需要在类加载时进行的操作。

  6. 静态成员可以是公共的(public)、私有的(private)或受保护的(protected)。这取决于如何访问和使用这些成员。通常情况下,静态成员应该以私有的方式来封装,以避免直接访问和修改。

  7. 静态成员可以是常量(final),这意味着它们的值不能被修改。静态常量通常使用大写字母表示,并且在类的声明中进行初始化。它们通常用作不变的全局配置或常用的常量值。

  8. 静态内部类是一个嵌套在另一个类中并被声明为静态的类。静态内部类与外部类的实例无关,并且可以直接访问外部类的静态成员。静态内部类对于将辅助类与其外部类相关联并封装在一起是很有用的。

  9. 静态方法可以在没有创建类的对象的情况下调用,这是由于它们只与类本身相关,而不是具体的对象。这使得静态方法适用于实用工具方法,这些方法与该类的对象状态无关。

  10. 静态成员的访问具有全局范围。这意味着它们可以被其他类中的任何地方访问,通过使用类名进行限定。

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

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

相关文章

Tampermonkey油猴插件-各大网盘批量分享,解放双手-下

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列

NetApp AFF C 系列全闪存存储的主要优势和软件特性

NetApp AFF C 系列全闪存存储 采用全新的闪存技术,同时辅以智能科技加持,将为您带来一个更为经济实惠的全闪存解决方案,它重新定义了安全性、可扩展性和可持续性。 为什么选择 AFF C 系列的新一代全闪存解决方案? 实现现代化&am…

Overleaf Docker编译复现计划

Overleaf Docker编译复现计划 Overleaf Pro可以支持不同年份的Latex镜像自由选择编译,这实在是一个让人看了心痒痒的功能。但是很抱歉,这属于Pro付费功能。但是我研究了一下,发现其实和Docker编译相关的代码,社区版的很多代码都没…

docker部署mongo过程

1、拉取MongoDB镜像,这里拉取最新版本。 docker pull mongo2、运行容器 docker run -d --name mongo -p 27017:27017 \ -e MONGO_INITDB_ROOT_USERNAMEadmin \ -e MONGO_INITDB_ROOT_PASSWORD123456 \ mongo:latest --auth#由于 mongodb 默认情况下,…

如何控制docker服务的日志输出?

引言 通过docker部署的线上服务,由于宿主机存储空间有限,加上长时间累积的客观条件下,会出现docker服务的控制台日志过大。再三思量后决定不输出控制台日志,从而从根源解决此问题。 在Docker Compose中,您可以通过添加…

【Linux】编写第一个小程序:进度条

文章目录 1. 预备知识1.1 简单认识几个函数1.1.1 sleep()1.1.2 fflush()1.1.3 usleep()1.1.4 memset() 1.2 缓冲区1.3 回车与换行 2. 编写入门版的进度条2.1 基本逻辑2.2 美化效果2.3 代码实现2.4 执行效果 3. 编写升级版的进度条3.1 代码实现3.2 执行效果 1. 预备知识 1.1 简…

OpenHarmony—子系统开发之内核概述

内核简介 用户最常见到并与之交互的操作系统界面,其实只是操作系统最外面的一层。操作系统最重要的任务,包括管理硬件设备,分配系统资源等,我们称之为操作系统内在最重要的核心功能。而实现这些核心功能的操作系统模块&#xff0…

【小白专用】C#关于角色权限系统

(C#)用户、角色、权限 https://www.cnblogs.com/huangwen/articles/638050.html 权限管理系统——数据库的设计(一) https://www.cnblogs.com/cmsdn/p/3371576.html 权限管理系统——菜单模块的实现(二) …

Java LeetCode刷题 单调栈

单调栈 单调栈概念 每日温度 单调栈 概念 单调栈(Monotonic Stack)是一个特殊的数据结构,它是一种栈,但具有单调性的特性。单调栈有两种类型:单调递增栈和单调递减栈。 在单调递增栈中,栈内的元素保持递…

安全防御之密码技术

密码学是信息安全的基础技术之一,是达到信息系统安全等级保护要求的核心技术支持,在身份验证、访问控制、文件加密、数据加密和安全传输中都得到广泛应用。其核心目标是保证信息的机密性、完整性和可用性。 密码学包括加密和解密两个部分。一般过程是&am…

Linux 【C编程】IO进阶— 阻塞IO、非阻塞IO、 多路复用IO、 异步IO

文章目录 1.阻塞IO与非阻塞IO1.1为什么有阻塞式?1.2非阻塞 2.阻塞式IO的困境3.并发IO的解决方案3.1非阻塞式IO3.2多路复用IO3.2.1什么是多路复用IO?3.2.1多路复用IO select原理3.2.1多路复用IO poll原理 3.3异步IO 1.阻塞IO与非阻塞IO 1.1为什么有阻塞式…

【教3妹学编程-算法题】统计出现过一次的公共字符串

3妹:哈哈哈哈哈哈,太搞笑了~ 呵呵呵呵呵呵 2哥:3妹干嘛呢, 笑的这么魔性! 3妹:在看王牌对王牌,老搞笑了 2哥:这季好像没有贾玲吧。 3妹:是啊,听说贾玲去导电影…

Vue入门六(前端路由的概念与原理|Vue-router简单使用|登录跳转案例|scoped样式)

文章目录 前要:前端路由的概念与原理1)什么是路由2)SPA与前端路由3)什么是前端路由4)前端路由的工作方式 一、Vue-router简单使用1)什么是vue-router2) vue-router 安装和配置的步骤① 安装 vue-router 包②…

React Native 桥接组件封装原生组件属性

自定义属性可以让组件具备更多的灵活性,所以有必要在JS 层通过自定义属性动态传值。 一、添加原生组件属性 因为 ViewManager 管理了整个组件的行为,所以要新增组件属性也需要在这里面(如 InfoViewManager)进行定义。 1、在Inf…

从DETR到Mask2Former(1):DETR-segmentation结构全解析

网上关于DETR做的detection的解析很多,但是DETR做Segmentation的几乎没有,本文结合DETR的论文与代码,对DETR做一个详细的拆解。理解DETR是理解Mask2Former的基础。 首先得把DETR-segmentation给run起来。Github上DETR的repository&#xff0…

【python入门】day26:统计字符串中出现指定字符的次数

案例 实际上if name“main”:就相当于是 Python 模拟的程序入口 。由于模块之间相互引用,不同模块可能都有这样的定义,而入口程序只能有一个,选中哪个入口程序取决于 ** ** name** **的值。 代码 #-*- coding:utf-8 -*- #开发时间&#xff…

SQL-分页查询and语句执行顺序

🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:重拾MySQL 🍹文章作者技术和水平很有限,如果文中出现错误&am…

Pytest插件pytest-cov:优雅管理测试覆盖率

在软件开发中,测试覆盖率是评估测试质量的关键指标之一。为了更方便地统计和管理测试覆盖率,Pytest插件"pytest-cov"应运而生。本文将介绍"pytest-cov"的基本用法和优雅管理测试覆盖率的方法。 什么是pytest-cov? pytest-cov 是Pyt…

7-4 jmu-Java-01入门-开根号 --笔记篇

题目 使用逐步逼近法对给定数值x求开根号。 逐步逼近法说明&#xff1a;从0开始逐步累加步长值。 步长0.0001&#xff0c;epsilon(误差)0.0001 循环继续的条件&#xff1a; 平方值<x 且 |x-平方值| > epsilon ###说明与参考 数值输出保留6位小数&#xff0c;使用S…

【C/C++】C语言的高级编程

C语言的高级编程 预定义宏宏展开下的#与##的使用常用的数据类型有结构体定义类型修饰符&#xff1a;对内存资源存放位置的限定&#xff0c;资源属性中位置的限定。 预定义宏 __FUNCTION__ //函数名 __LINE__ //行号 __FILE__ //文件名printf(" the %s,%s,%d\n"…