当前位置: 首页 > news >正文

Java基础(十):关键字static详解

Java基础系列文章

Java基础(一):初识Java——发展历程、技术体系与JDK环境搭建

Java基础(二):八种基本数据类型详解

Java基础(三):逻辑运算符详解

Java基础(四):位运算符详解

Java基础(五):流程控制全解析——分支(if/switch)和循环(for/while)的深度指南

Java基础(六):数组全面解析

Java基础(七): 面向过程与面向对象、类与对象、成员变量与局部变量、值传递与引用传递、方法重载与方法重写

Java基础(八):封装、继承、多态与关键字this、super详解

Java基础(九):Object核心类深度剖析

Java基础(十):关键字static详解

目录

  • 一、static的基本概念
  • 二、static变量
    • 1、静态变量(类变量)
    • 2、静态变量的初始化
    • 3、静态变量 vs 实例变量
    • 4、静态变量的线程安全性
  • 三、static方法
    • 1、静态方法
    • 2、静态方法的使用限制
  • 四、static代码块
  • 五、static嵌套类
    • 1、静态内部类
    • 2、常见用途(Builder模式)
  • 六、静态导入

一、static的基本概念

  static是Java中的一个修饰符,可用于修饰类的成员变量方法代码块嵌套类。被static修饰的成员属于类本身,而不是类的某个实例对象。这意味着静态成员在类加载时就会被初始化,并且所有该类的实例共享同一份静态成员。

二、static变量

1、静态变量(类变量)

  • 静态变量属于类,而不是某个特定的对象实例。所有实例共享同一个静态变量
public class Counter {// 静态变量private static int count = 0;public Counter() {count++; // 每次创建实例时count增加}public static int getCount() {return count;}
}// 使用示例
public class Main {public static void main(String[] args) {Counter c1 = new Counter();Counter c2 = new Counter();Counter c3 = new Counter();System.out.println("创建的实例数量: " + Counter.getCount()); // 输出: 3}
}

2、静态变量的初始化

  • JVM加载类时,会执行类初始化​(Class Initialization),此时静态变量会被显式赋值(若未显式赋值则使用默认值)
    • 默认值规则​:数值类型为0,布尔类型为false,引用类型为null
    • 显式赋值​:在定义中直接赋值,或在静态代码块中赋值(二者执行顺序按代码编写顺序)
public class InitializationExample {// 声明时初始化static int a = 10;// 静态代码块初始化static int b;static {b = 20;}// 默认赋值static int c;public static void main(String[] args) {System.out.println("a=" + a);  // 输出10System.out.println("b=" + b);  // 输出20System.out.println("c=" + c);  // 输出0}
}

3、静态变量 vs 实例变量

特性静态变量实例变量
内存分配类加载时分配,在方法区对象创建时分配,在堆内存
生命周期与类相同与对象实例相同
访问方式类名.变量名 或 对象.变量名只能通过对象.变量名
共享性所有实例共享每个实例独有

4、静态变量的线程安全性

  • 静态变量被所有实例共享,多线程环境下修改可能导致数据不一致(需通过synchronizedLockAtomicXXX类保证原子性)
public class ThreadSafeCounter {private static int count = 0;private static final Object lock = new Object();// 线程不安全的递增public static void unsafeIncrement() {count++;}// 线程安全的递增public static void safeIncrement() {synchronized (lock) {count++;}}// 使用AtomicInteger实现线程安全private static AtomicInteger atomicCount = new AtomicInteger(0);public static void atomicIncrement() {atomicCount.incrementAndGet();}
}

三、static方法

1、静态方法

  • 静态方法属于类,而不是类的实例
  • 可以通过类名直接调用,无需创建实例
public class MathUtils {// 静态变量private static final double PI = 3.14159;// 静态方法public static double calculateCircleArea(double radius) {return PI * radius * radius;}// 另一个静态方法,可以调用其他静态方法public static double calculateCircleCircumference(double radius) {return 2 * PI * radius;}
}// 使用示例
public class Main {public static void main(String[] args) {double area = MathUtils.calculateCircleArea(5.0);double circumference = MathUtils.calculateCircleCircumference(5.0);System.out.println("面积: " + area);System.out.println("周长: " + circumference);}
}

2、静态方法的使用限制

  1. 不能使用this和super关键字:因为静态方法不依赖于任何实例
  2. 不能直接访问实例变量和实例方法:只能直接访问静态成员
  3. 不能被重写:静态方法可以被子类"隐藏",但不能被重写

代码示例:重写 vs. 隐藏

  • 隐藏:​​ 针对静态方法、静态变量和实例变量
  • 发生在编译时,基于引用的声明类型(等号左边的类型)来决定调用哪个方法或字段
  • 这就是静态绑定或早期绑定
class Animal {// 这是一个静态方法,将被“隐藏”public static void staticMethod() {System.out.println("Animal: Static Method");}// 这是一个实例方法,将被“重写”public void instanceMethod() {System.out.println("Animal: Instance Method");}
}class Dog extends Animal {// 隐藏父类的静态方法 (使用 @Override 注解会报错,因为它不是重写)public static void staticMethod() {System.out.println("Dog: Static Method");}// 重写父类的实例方法 (使用 @Override 注解是正确且推荐的)@Overridepublic void instanceMethod() {System.out.println("Dog: Instance Method");}
}public class Test {public static void main(String[] args) {// 关键:声明类型为 Animal,实际对象为 DogAnimal myAnimal = new Dog();// 调用静态方法 - 隐藏 (看引用类型 Animal)myAnimal.staticMethod(); // 输出: Animal: Static Method// 调用实例方法 - 重写 (看对象类型 Dog)myAnimal.instanceMethod(); // 输出: Dog: Instance Method// 通过类名调用静态方法(正确方式)Animal.staticMethod(); // 输出: Animal: Static MethodDog.staticMethod();    // 输出: Dog: Static Method}
}

四、static代码块

  • 静态代码块在类加载时执行,且只执行一次,常用于初始化静态变量或执行只需进行一次的操作
public class DatabaseConnection {private static Connection connection;// 静态代码块static {try {// 初始化数据库连接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");System.out.println("数据库连接已建立");} catch (SQLException e) {System.out.println("数据库连接失败: " + e.getMessage());}}public static Connection getConnection() {return connection;}
}

五、static嵌套类

1、静态内部类

  • static嵌套类(静态内部类)是声明为static的内部类
    • 不依赖于外部类的实例
    • 可以访问外部类的static成员
    • 不能直接访问外部类的非static成员
    • 可以包含static和非static成员
public class OuterClass {private static String staticField = "静态字段";private String instanceField = "实例字段";// 静态嵌套类public static class StaticNestedClass {public void print() {System.out.println(staticField); // 可以访问外部类的静态成员// System.out.println(instanceField); // 错误:不能访问外部类的实例成员}}// 内部类(非静态)public class InnerClass {public void print() {System.out.println(staticField); // 可以访问静态成员System.out.println(instanceField); // 也可以访问实例成员}}
}// 使用示例
public class Main {public static void main(String[] args) {// 依赖外部类,需要先创建外部类,再创建内部类实例OuterClass outer = new OuterClass();OuterClass.InnerClass inner = outer.new InnerClass();inner.print();// 不需要外部类实例,直接创建静态嵌套类实例OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();nested.print();}
}

2、常见用途(Builder模式)

示例:自定义一个带有 Builder 模式的类

public class User {// 成员变量private String name;private Integer age;private String email;// 私有构造方法,只能通过 Builder 构建private User(String name, Integer age, String email) {this.name = name;this.age = age;this.email = email;}public static UserBuilder builder() {return new UserBuilder();}// 静态内部类 Builderpublic static class UserBuilder {private String name;private Integer age;private String email;private UserBuilder() {}// 设置参数的方法,返回 Builder 本身,支持链式调用public UserBuilder name(final String name) {this.name = name;return this;}public UserBuilder age(final Integer age) {this.age = age;return this;}public UserBuilder email(final String email) {this.email = email;return this;}// 构建 User 对象public User build() {return new User(this.name, this.age, this.email);}}
}

使用方式:

public class Main {public static void main(String[] args) {User user = User.builder().name("xuchang").age(18).email("xuchang@gmail.com").build();System.out.println(user);}
}

六、静态导入

  • Java 5引入了static导入功能,允许直接使用其他类中定义的static成员而不需要类名前缀
// 导入Math类的所有static成员
import static java.lang.Math.*;public class StaticImportExample {public static void main(String[] args) {// 直接使用Math类的static方法,无需Math.前缀double result = sin(PI / 2) + cos(0);System.out.println("计算结果: " + result);  // 输出2.0}
}
  • 也可以只导入特定的static成员
// 只导入Math类的sqrt和PI
import static java.lang.Math.sqrt;
import static java.lang.Math.PI;public class SelectiveStaticImport {public static void main(String[] args) {double area = PI * sqrt(2) * sqrt(2);  // 计算半径为√2的圆的面积System.out.println("面积: " + area);  // 输出约6.283185307179586}
}

文章转载自:

http://D5VhvpqN.pcgrq.cn
http://vGoyr68V.pcgrq.cn
http://Xx03Sptj.pcgrq.cn
http://ZhwM9boG.pcgrq.cn
http://g5Zwov2F.pcgrq.cn
http://CUEFLsW6.pcgrq.cn
http://f0mdyedn.pcgrq.cn
http://EwZ2Ifxy.pcgrq.cn
http://r1FRMb6i.pcgrq.cn
http://uyNU1eO9.pcgrq.cn
http://tsNV7r5m.pcgrq.cn
http://tjKAVnON.pcgrq.cn
http://lVvKNYGC.pcgrq.cn
http://2vnRYytG.pcgrq.cn
http://KtGuhv5V.pcgrq.cn
http://Lffw7Z3w.pcgrq.cn
http://fOztZJLG.pcgrq.cn
http://Qmp6CTTu.pcgrq.cn
http://gwP4ZBqC.pcgrq.cn
http://ra6CjnSM.pcgrq.cn
http://lmt5tDzO.pcgrq.cn
http://PfLovon3.pcgrq.cn
http://XxD72J4o.pcgrq.cn
http://4p0fHWW7.pcgrq.cn
http://mnQjkMUF.pcgrq.cn
http://NsZctf2A.pcgrq.cn
http://lsTXXPqs.pcgrq.cn
http://7ldVGomG.pcgrq.cn
http://68c0Xfb7.pcgrq.cn
http://rrEGuO87.pcgrq.cn
http://www.dtcms.com/a/362430.html

相关文章:

  • 一文带你入门 AT 指令集:从串口通信到模块控制
  • 【Qt开发】按钮类控件(二)-> QRadioButton
  • lua脚本在redis中执行是否是原子性?
  • 每次开机弹出‘killer network manager launcher’链接无应用打开”解决方案
  • 【Lua】题目小练13
  • CodeForge v25.0.3 发布:Web 技术栈全覆盖,编辑器个性化定制新时代
  • 分页功能设计
  • Docker镜像指南:从核心命令到离线迁移实战
  • 实时视频链路的产业化路径:多场景应用与长期思考
  • 力扣:2458. 移除子树后的二叉树高度(dfs序)
  • leetcode111. 二叉树的最小深度
  • 前缀和之距离和
  • 基于SQLite的智能图片压缩存储系统:代码解析与实战应用
  • Time-MOE 音频序列分类任务
  • form表达和实体类通常有什么不同
  • C#中的克隆:从理论到实践
  • Elasticsearch Java开发(SpringBoot)
  • 从零开始的云计算生活——第五十六天,临深履薄,kubernetes模块之etcd备份恢复和集群升级指南
  • Prettier代码格式化工具测评:支持JS/TS/Vue多语言,兼容ESLint实现团队代码格式统一
  • 在 PySpark 中解锁窗口函数的力量,实现高级数据转换
  • 什么是Token?——理解自然语言处理中的基本单位
  • 毕业项目推荐:68-基于yolov8/yolov5/yolo11的水稻虫害检测识别系统(Python+卷积神经网络)
  • Python OpenCV图像处理与深度学习: Python OpenCV图像配准入门
  • 深度学习中的数据增强实战:基于PyTorch的图像分类任务优化
  • 云计算学习100天-第43天-cobbler
  • 【linux仓库】万物至简的设计典范:如何用‘文件’这一个概念操纵整个Linux世界?
  • 【数据分享】土地利用shp数据分享-内蒙古
  • Python应用——ffmpeg处理音视频的常见场景
  • 谷歌AdSense套利是什么?怎么做才能赚到钱
  • 安卓QQ闪照获取软件(支持TIM)